Get started
Errors, rate limits and CORS
Every error is a JSON object with an error message and a standard HTTP status. Simple actions that succeed return {"ok": true}.
What does an error look like?
{ "error": "API key is read-only" }
The error text is meant for people and logs. Branch on the HTTP status in your code, and treat the message text as informational. Unknown fields in request bodies are ignored rather than rejected.
Some errors add fields:
402adds"code": "payment_required".- Errors from Meta on the Cloud API channel endpoints add
meta_code,meta_subcodeandmeta_titlewhen Meta provides them. 502from Start a conversation adds theconversationthat was created before the send failed.- A path that does not exist returns
404with{"error": "not found", "code": "not_found"}, so you can tell a wrong URL from a missing resource.
Which status codes are used?
| Status | When | Example error |
|---|---|---|
400 | Invalid input or a malformed id; session request without a workspace. | invalid conversation id, message body is required, workspace required (X-Tenant-ID) |
401 | Missing, wrong, revoked or expired credentials. | invalid or expired API key, unauthorized |
402 | Subscriptions are enforced and the workspace has none. | subscription required |
403 | Not allowed for this key or user. | API key is read-only, API keys cannot administer workspaces, API key belongs to a different workspace, admin required, forbidden |
404 | The resource does not exist in this workspace (or is not visible to an agent). | conversation not found, contact not found |
409 | Conflicts with the current state. | whatsapp is not connected, a contact with this phone number already exists |
413 | A request body is too large (Meta callback). | payload too large |
429 | Too many attempts on a rate-limited endpoint. | too many attempts, please wait a minute and try again |
500 | Unexpected server error, or an error from WhatsApp or Meta while sending. | varies |
502 | WhatsApp or Meta rejected an upstream call. | meta rejected the template request: … |
503 | A dependency is down (health check returns status: "degraded"), or the guided Meta signup is not configured on the server. | customer signup is awaiting platform configuration |
405 and 422 are not used.
What should I retry?
| Status | Retry? |
|---|---|
500, 502, 503 | Yes, with exponential backoff (for example 1 s, 2 s, 4 s, up to a few attempts). |
429 | Yes, after the number of seconds in Retry-After. |
409 whatsapp is not connected | Only after the connection is back (check QR session status). |
400, 401, 402, 403, 404 | No. Fix the request, key or permissions first. |
A send that failed with 500 may in rare cases still have reached WhatsApp. Before retrying a send, check the latest messages of the conversation.
Are there rate limits?
Only public endpoints are rate limited, per client IP address, with a sliding window kept in memory. These are the sign-in and email endpoints (the website’s contact form has its own limit):
| Endpoints | Limit |
|---|---|
POST /api/auth/register, /login, /reset-password, /verify-email, /google/confirm | 10 per minute, shared by these endpoints |
POST /api/auth/forgot-password, /resend-verification | 5 per minute, shared by these endpoints |
GET /api/auth/google/start, /google/pending | 20 per minute, shared by these endpoints |
Over the limit you get 429 with too many attempts, please wait a minute and try again and a Retry-After header in seconds. There are no X-RateLimit-* headers.
Requests authenticated with API keys are not rate limited today. Limits may be added later, so handle 429 and Retry-After everywhere, and avoid tight polling loops: use webhooks or live events instead.
Which list endpoints are capped?
No list endpoint has pagination except messages. Lists return at most:
| Endpoint | Cap |
|---|---|
| List conversations | 30 most recent |
| List messages | limit up to 100 per page (default 50), paginated |
| Contacts, templates, knowledge articles | 500 newest |
| Webhooks | 10 per workspace |
| Template sync | First page from Meta (up to 100) |
How does CORS work?
The API answers OPTIONS preflight requests with 204 and allows the methods GET, POST, PUT, PATCH, DELETE, OPTIONS and the request headers Content-Type, Authorization and X-Tenant-ID. No response headers are exposed to scripts beyond the defaults. Never use API keys from browser code; call the API from your server.