Developer docs
API error reference
Status codes, typed error codes, retry handling, and Idempotency-Key behavior.
Status handling
| Status | Meaning | Client action |
|---|---|---|
| 200 | Read succeeded | Continue. |
| 201 | Resource created | Store the returned id and any one-time secret immediately. |
| 202 | Message accepted | Poll message logs or subscribe to status webhooks. |
| 401 | Missing auth context | Attach tenant, user, and role headers or valid API credentials. |
| 403 | Role or MFA required | Ask an owner/operator to perform the privileged action. |
| 404 | Tenant-scoped resource missing | Treat as not found; do not retry without new input. |
| 409 | State conflict | For idempotency conflicts, fix the request body or use a new key. |
| 422 | Validation failed | Fix the request shape before retrying. |
| 423 | Sending halted | Stop sends; review suspension status and appeal/export paths. |
| 429 | Rate or sending limit | Back off and retry after capacity resets. |
| 500 | Unexpected server error | Retry with jitter; escalate if repeated. |
Typed errors
| Code | Status | Meaning |
|---|---|---|
auth_context_required | 401 | No authenticated tenant/user scope was provided. |
owner_required | 403 | Privileged owner/admin/operator action attempted by member. |
operator_required | 403 | Global/platform action attempted outside operator role. |
project_not_found | 404 | Project does not exist in the authenticated tenant. |
api_key_not_found | 404 | API key does not exist in the authenticated tenant. |
idempotency_key_reused | 409 | Same Idempotency-Key was reused with a different body. |
sending_halted | 423 | Workspace sending status or a safety restriction blocks new sends. |
tenant_rate_limited | 429 | Tenant token bucket is empty. |
provider_rate_limited | 429 | Provider token bucket is empty. |
daily_recipient_limit_exceeded | 429 | Warmup daily recipient cap would be exceeded. |
outbox_item_not_found | 404 | Dead-letter or scheduled item is not in this tenant. |
outbox_item_not_dead_letter | 409 | Only dead-letter items can be replayed. |
message_not_cancellable | 409 | Only future pending sends can be cancelled. |
Retry and idempotency
| Rule | Guidance |
|---|---|
| Safe to retry | 401 after token refresh, 429, transient 5xx, provider timeout |
| Do not blind retry | 403, 404, 409, 422, 423 |
| Use jitter | Start at 1-2s, double to 30s, cap retries by workflow criticality |
| Use idempotency | Send Idempotency-Key on POST /v1/messages and setup writes |