Appearance
Errors
Error responses are JSON:
json
{"error": "human-readable text", "kind": "machine_readable_kind"}kind is present where the status alone is ambiguous. Match on the status and kind; the error text is for humans and is not part of the contract.
Kinds
| Kind | Status | Meaning | Retry |
|---|---|---|---|
invalid_lease | 400 | The lease token is malformed — a bug or tampering. | Never. |
dedup_disabled | 400 | The send carries a dedup key but the queue has no dedup window. | No — set dedupWindowSeconds or drop the key. |
unknown_header | 400 | A Spooler-* request header the operation does not define — likely meant for another endpoint. | No — fix the request. |
retention_limit | 403 | The requested retention exceeds the plan's limit. | No. |
queue_not_found | 404 | The queue does not exist. A verdict, not lag. | No. |
spool_not_found | 404 | Can be lag right after the spool was created. | Yes. |
queue_deleting | 409 | The queue refuses the operation while its deletion completes. | No. |
queue_busy | 409 | A concurrent settings change lost a race. | Yes. |
dedup_in_flight | 409 | A send with the same dedup key has not settled yet. | Yes, after it settles. |
stale_lease | 410 | The token verified but no longer settles anything: expired, already settled, or predates a primary change. | Receive or peek again. |
payload_too_large | 413 | The message exceeds the size limit (see limits). | No. |
rate_limited | 429 | The per-account request rate cap is exceeded. | After the Retry-After seconds. |
operation_unconfirmed | 500 | The write was accepted but its durability is unknown. | A send: only on a queue with a dedup window, carrying the same key (see deduplication). |
spool_full | 507 | The spool holds its plan's maximum stored messages or payload bytes (see limits). | After making room. |
Statuses without a kind mean what HTTP says: 401 bad credentials, 402 the account is suspended, 403 without a kind is the plan's queue limit, 411 a send without Content-Length, 503 the spool is momentarily unavailable — retry.

