Errors & rate limits
Error format
Every error has the same shape:
json
{
"error": {
"code": "validation_failed",
"message": "to: Invalid phone number",
"requestId": "req_01J…",
"details": [{ "path": "to", "message": "Invalid phone number" }]
}
}Log requestId and include it when you contact support.
Error codes
| HTTP | code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed JSON or request |
| 422 | validation_failed | Body failed validation; see details |
| 401 | unauthorized | Missing, invalid, expired or revoked API key |
| 403 | forbidden | Key is missing the required scope |
| 404 | not_found | Resource doesn't exist in this workspace |
| 409 | conflict | State conflict: no WhatsApp number linked, resending an answered order, resending a verification that is no longer pending |
| 413 | payload_too_large | Body too large |
| 429 | rate_limited | Too many requests; retry later |
| 500 | internal_error | Unexpected error; safe to retry with the same Idempotency-Key |
| 503 | service_unavailable | WhatsApp sending temporarily unavailable |
Rate limits
| Limit | Value |
|---|---|
| New OTP verifications per recipient | 5 per 10 minutes |
| New OTP verifications per workspace | 300 per hour |
| OTP resend cooldown | 30 seconds |
| OTP sends per verification | 5 |
| Wrong OTP attempts | 5, then failed |
| Order confirmation resends | 5 per order / hour |
Messages also use plan credits (1 credit ≈ 1 delivered WhatsApp message). Retries never count twice.