Work queues (mailboxes)
Work queues and inboxes (mailboxes), and settling the messages delivered from them.
All paths are relative to the API base URL (https://api.getrunstate.com) and require Authorization: Bearer <api key>. See the API overview for authentication, idempotency and the error envelope.
GET /mailboxes
Section titled “GET /mailboxes”GET /v1/spaces/{spaceId}/mailboxesRead-only mailbox list for consoles.
- Key permission:
coordination_read
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
Responses
| Status | Meaning |
|---|---|
200 |
Mailboxes |
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/mailboxes" \ -H "Authorization: Bearer $RUNSTATE_API_KEY"POST /mailboxes
Section titled “POST /mailboxes”POST /v1/spaces/{spaceId}/mailboxesCreate work mailbox or inbox.
- Key permission:
resource_config - Idempotency-Key header: required
- TypeScript SDK:
rs.mailboxes.ensure() - Python SDK:
rs.mailboxes.ensure()
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | |
mode |
string | no | one of WORK, INBOX; default "WORK" |
recipientId |
string | no | |
backlogLimit |
integer | no | default 1000 |
Responses
| Status | Meaning |
|---|---|
201 |
Created |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/mailboxes" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"<name>"}'GET /mailboxes/{id}/messages
Section titled “GET /mailboxes/{id}/messages”GET /v1/spaces/{spaceId}/mailboxes/{id}/messagesRead-only message list with optional state filter.
- Key permission:
coordination_read
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Responses
| Status | Meaning |
|---|---|
200 |
Messages |
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/mailboxes/<id>/messages" \ -H "Authorization: Bearer $RUNSTATE_API_KEY"POST /mailboxes/{id}/messages
Section titled “POST /mailboxes/{id}/messages”POST /v1/spaces/{spaceId}/mailboxes/{id}/messagesSend scoped message (work_key dedup applies)
- Key permission:
coordination_write - Idempotency-Key header: required
- TypeScript SDK:
mailbox.send() - Python SDK:
mailbox.send()
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
scopeId |
string (uuid) | yes | |
payload |
any JSON | yes | |
workKey |
string | no | |
deadline |
string (date-time) | no |
Responses
| Status | Meaning |
|---|---|
200 |
Dedup replay of committed send |
201 |
Message id |
409 |
Error envelope {"error":{"code","message","requestId"}} |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/mailboxes/<id>/messages" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"scopeId":"<run id>","payload":{"example":true}}'POST /mailboxes/{id}/recv
Section titled “POST /mailboxes/{id}/recv”POST /v1/spaces/{spaceId}/mailboxes/{id}/recvReceive-and-claim next ready message for a scope.
- Key permission:
coordination_write - TypeScript SDK:
mailbox.receive(), mailbox.consume() - Python SDK:
mailbox.receive(), mailbox.consume()
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
scopeId |
string (uuid) | yes | |
holder |
string | yes | |
holderSession |
string | yes | |
leaseSeconds |
integer | no | default 30 |
waitMs |
integer | no | 0–120000; Long-poll an empty receive for up to this many milliseconds (capped by the server at api.longPollMaxWaitMs; 0 or absent answers at once). Returns as soon as work is available, when the wait ends, or when the API starts draining. An empty long poll of at least 1000 ms does not count toward request rate limits. |
Responses
| Status | Meaning |
|---|---|
200 |
Message with claim token |
204 |
No ready message (after the waitMs long poll |
409 |
Error envelope {"error":{"code","message","requestId"}} |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/mailboxes/<id>/recv" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"scopeId":"<run id>","holder":"worker-1","holderSession":"<session id>"}'POST /messages/{id}/renew
Section titled “POST /messages/{id}/renew”POST /v1/spaces/{spaceId}/messages/{id}/renewRenew current receive claim; also extends pool grants admitted with this delivery.
- Key permission:
coordination_write - TypeScript SDK:
delivery.renew() (automatic inside consume) - Python SDK:
delivery.renew() (automatic inside consume)
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes | |
leaseSeconds |
integer | no | 5–600; default 30 |
Responses
| Status | Meaning |
|---|---|
200 |
Renewed |
409 |
Error envelope {"error":{"code","message","requestId"}} |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/messages/<id>/renew" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"token":"<lease token>"}'POST /messages/{id}/complete
Section titled “POST /messages/{id}/complete”POST /v1/spaces/{spaceId}/messages/{id}/completeAck plus optional result atomically.
- Key permission:
coordination_write - TypeScript SDK:
delivery.complete() - Python SDK:
delivery.complete()
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes | |
result |
object | no | Optional. payload alone records the task outcome without publishing a result message; mailboxId and scopeId must be sent together to also publish the result to that mailbox. |
result.mailboxId |
string (uuid) | no | |
result.scopeId |
string (uuid) | no | |
result.payload |
any JSON | no | |
result.workKey |
string | no |
Responses
| Status | Meaning |
|---|---|
200 |
ACKED |
409 |
Error envelope {"error":{"code","message","requestId"}} |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/messages/<id>/complete" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"token":"<lease token>"}'POST /messages/{id}/nack
Section titled “POST /messages/{id}/nack”POST /v1/spaces/{spaceId}/messages/{id}/nackRetry or reject current claim.
- Key permission:
coordination_write - TypeScript SDK:
delivery.retry() / delivery.reject() - Python SDK:
delivery.retry() / delivery.reject()
Path parameters
| Name | Type | Notes |
|---|---|---|
spaceId |
string (uuid) | required |
id |
string (uuid) | required |
Request body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes | |
retry |
boolean | yes |
Responses
| Status | Meaning |
|---|---|
200 |
New message state |
409 |
Error envelope {"error":{"code","message","requestId"}} |
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/messages/<id>/nack" \ -H "Authorization: Bearer $RUNSTATE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"token":"<lease token>","retry":true}'