Skip to main content

Error envelope

Every refusal has one shape:
Errors never carry stack traces, secrets or internal hostnames.

Reasons

A refusal can carry a finer reason beside its code. A reason is stable and safe to branch on; the message is for people and may change. An engine in a draft, a session or a runtime reading is named by a sealed Sempera name (engine_ then letters and digits) and a voice by its Sempera voice id; a refusal never repeats the engine or the engine’s own id.

A paused workspace

While a workspace is paused, a signed-in member gets 403 workspace_suspended on every request that would take a new action, and still reads and exports. Its API keys behave differently: a key of a paused workspace is refused as an unknown key would be, with 401 invalid_credential, on reads as well as writes, and works again unchanged when the workspace is restored. Do not rotate or reissue keys in response to that 401 without first checking the workspace’s status in the App. A workspace that only ever used API keys still has a road to its data while paused. The workspace owner signs in to the Sempera App, where the agent export, the call export and the call list keep working, and where the data deletion and workspace closure paths stay open. Nothing is deleted by a pause.

Pagination

Most Sempera-native list routes take limit (1 to 200, default 50) and cursor. Responses are {"object": "list", "data": [...], "has_more": true, "next_cursor": "..."}. Pass next_cursor back unchanged; cursors are opaque. Compatibility facade routes keep their observed external envelopes, including tools/hasMore/nextCursor, data.count/data.integrations, data plus errors, and voices-only shapes. Check openapi.json for the exact response shape on each route.

Idempotency

Send Idempotency-Key (up to 255 characters) on POST /v1/agents, /publish, /rollback, /v1/sessions, /v1/calls, /v1/phone-numbers, /v1/tools, /v1/tools/{id}/execute, /v1/snippets, /v1/snippets/{id}/publish, /v1/integrations, /v1/tests, /v1/evals, /v1/evals/user-templates, /v1/evals/run and /v1/webhooks. A retry with the same key and the same request replays the stored answer with Idempotent-Replayed: true; the same key with a different request is refused with 409 idempotency_key_reused. Keys live 24 hours and are scoped to your workspace.

Rate limits

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds). A 429 carries Retry-After in seconds. Back off exponentially. Separately from these request limits, a workspace owner may cap the outbound calls the workspace places per UTC hour and per UTC day. POST /v1/calls over a cap answers 429 rate_limited with retry_after_s in the error, and places nothing; if the cap cannot be read it answers 503 service_unavailable and places nothing (Owner features in the App).

Body size

JSON bodies are limited to 1 MiB; knowledge uploads to 25 MiB.