Developer API errors and request limits
Last updated: 11 November 2026 · 6 min read
The API returns 2xx on success and 4xx or 5xx on errors. Every response has an X-Request-Id header: when you write to support ([email protected]), send this value, and we find the request in the log quickly.
Steps
-
1
Error shape
Token, scope, limit and path errors share one shape:
{ "error": { "code": "insufficient_scope", "message": "This action needs the messages:send permission.", "required_scopes": ["messages:send"], "request_id": "3f9c2a1e-8b7d-4c6a-9e15-2d4b7a0c9f31" } }codeis stable: check it in your code.messageis for people and can change. It comes in English withAccept-Language: en. A 403 response also carries aWWW-Authenticateheader. An endpoint's own checks (a required field, a wrong value) still use the older shape, usually with 422:{ "error": "..." }or{ "message": "...", "attributes": [...] }./oauth/*errors follow the OAuth shape:{ "error": "invalid_client" }. -
2
Token and permission errors
- 401
invalid_token: the token is missing, unknown or revoked. Check the header:Authorization: Bearer clomni_pat_xxx. - 401
token_expired: the token has expired. A personal access token works for 30-365 days, an app token for 1 hour. - 403
insufficient_scope: the token does not have the scope. Readrequired_scopes, add the scope to the app and send it for review, and after approval create a new token and choose that scope. - 403
endpoint_not_available: this endpoint is not open to developer tokens and is not in the API reference. - 403
app_not_approved: the app has no approved scope left. - 403
app_suspended: Clomni suspended the app, or the app is archived. Read the reason in the email. - 403
app_owner_not_admin: the app owner is no longer an administrator in the workspace. It works again once the role is given back. - 403
installation_owner_not_admin: the person who connected the public app is no longer an administrator, and the app has to be connected again. - 403
account_suspended: the workspace is suspended, and onlyworkspace:readworks.
- 401
-
3
Other errors
- 400
invalid_request: the path or a parameter is wrong (for examplelimitis outside 1-100). - 402
ai_credit_spent: the workspace's AI credit has run out (POST /ai_agents/{ai_agent_id}/ask). Do not retry automatically. - 404
not_found: the object does not exist or belongs to another workspace. 404test_channel_missing: no test channel has been created. - 403
test_channel_webhook: a test channel cannot have a webhook address. 403sandbox_restricted: sending outside is blocked in an old sandbox. - 409
conflict: a second export at the same time. 409idempotency_key_reused: the sameIdempotency-Keycame with a different body. 409idempotency_key_in_progress: a request with the same key is still running. - 422: the endpoint's own check, for example a second contact with the same email. Fix the body.
- 500
internal_error: an error on our side. Try again a little later. If it repeats, write to us with therequest_id.
Sending a message is asynchronous: when the 24-hour window on WhatsApp is closed or the channel is not connected, the request is accepted and then the message becomes
failed. The reason is in the message'scontent_attributes.external_errorfield. When WhatsApp QR returns the new chat restriction (463), do not send again: each attempt makes the restriction longer. - 400
-
4
When you can retry
- 400, 401, 403, 404, 422: do not retry, fix the cause first.
- 429: wait as many seconds as the
Retry-Afterheader says. - 500, 502, 503, 504 and network errors: with growing pauses (1, 2, 4, 8 seconds plus a random extra), at most 5 times.
When you retry a POST, send an
Idempotency-Keyso that the message does not go twice. -
5
Request limits
- General: 300 requests a minute per token.
- All tokens of an app together: 600 requests a minute. Creating more tokens does not raise the limit.
GET /sync/*: 60 a minute per token.POST /conversations/{conversation_id}/messages: 60 a minute per token.POST /oauth/token: 20 a minute perclient_idand IP.POST /exports: 1 job at a time per workspace, 6 a day.
Every
/v1response except/v1/meand/v1/oauth/*carries theRateLimit-Limit,RateLimit-RemainingandRateLimit-Reset(seconds) headers. Slow down whenRateLimit-Remaininggets close to zero. -
6
When you get 429
When a limit is exceeded, the response is 429
rate_limitedwith aRetry-Afterheader. Do not send requests with the same token until that time has passed. If the header is missing, wait with growing pauses. Do not fetch the list again every minute: get changes through webhooks and catch what you missed withupdated_since. Refresh an app token when it expires, not before every request. If you need a higher limit, write to [email protected] with the app, the endpoint, the expected volume and the reason.The API limit does not lift a channel's own limit: a WhatsApp Business API number has a daily limit and a quality rating set by Meta, and a WhatsApp QR number can be blocked for too many or unwanted messages.