The envelope
Section titled “The envelope”Every /public/v1/* error responds with the same body, whatever the HTTP status:
{ "error": "PERMISSION_DENIED", "message": "You do not have the required permission for this action", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "details": {}}error— the code from the table below; the only field your integration should branch on. It never changes shape within/public/v1(see Versioning).message— human-readable, in English, meant for debugging — don’t show it as-is to your end user or branch logic on it, its wording can change without notice.request_id— include it if you write to support about a specific error; it helps us find the exact request in our logs.details— extra context (e.g. which fields failed validation); never the stable part of the contract, treat it as informational.
Error catalog
Section titled “Error catalog”| HTTP | error | When it shows up |
|---|---|---|
| 401 | INVALID_CREDENTIALS | The key doesn’t exist, was copied wrong, or is revoked. |
| 401 | TOKEN_EXPIRED | The key is past its expiration date. |
| 403 | PERMISSION_DENIED | The key doesn’t have the exact scope the endpoint requires — see Authentication. |
| 403 | PLAN_NOT_ELIGIBLE | The key’s owning tenant isn’t on a Pro or Enterprise plan — see Plans and limits. |
| 404 | NOT_FOUND | The resource doesn’t exist, or belongs to another tenant — same response either way, so we never confirm someone else’s data exists. |
| 409 | WHATSAPP_SESSION_WINDOW_CLOSED | POST /conversations/{id}/messages to a WhatsApp contact whose 24h window is closed — use POST /conversations/start with an approved template instead. The real send is never attempted. |
| 422 | VALIDATION_ERROR | The request body or parameters don’t match the endpoint’s schema — check details. |
| 422 | IDEMPOTENCY_KEY_REUSE_MISMATCH | Only if you send the optional Idempotency-Key header: the same value was already used with a DIFFERENT body on an earlier request. Mint a fresh key for a genuinely different request. |
| 429 | RATE_LIMIT_EXCEEDED | You went over your request quota — see Plans and limits for the X-RateLimit-* headers. |
A FastAPI validation 422 (malformed body, wrong type) uses the same envelope, with details listing each
field that failed.
