View as Markdown

Errors and limits

Error shape

{
  "success": false,
  "request_id": "req_e097717d1d433831",
  "error": {
    "code": "recipient_not_opted_in",
    "message": "The recipient has not opted in to your messages yet.",
    "type": "invalid_request",
    "param": "to",
    "upstream": { "provider": "meta", "code": 131047 },
    "doc_url": "https://www.fiitsa.com/api-docs/erreurs"
  }
}

Branch your code on code, never on message. The code is stable and documented; the message may be reworded or translated.

When WhatsApp refuses, upstream.code carries Meta's own error code, which you can look up in their documentation.

Codes

CodeHTTPMeaning
missing_api_key401No key provided
invalid_api_key401Unknown or revoked key
insufficient_scope403The key lacks the required scope
plan_required403The plan does not include API access
whatsapp_not_connected403No number linked to the store
unsupported_field400Unrecognised or forbidden field
missing_parameter400Required parameter missing
unknown_route404Route does not exist
method_not_allowed405Known route, wrong verb
meta_rejected422WhatsApp refused
rate_limited429Rate exceeded
upstream_unavailable503Temporary unavailability
gateway_timeout504No response within the budget

Rate limiting

60 requests per 10 seconds in burst, 600 per minute sustained.

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. On a 429, honour the Retry-After header.

These limits protect against an accidental loop. The number of messages itself is not capped.

Support

Every response carries X-Fiitsa-Request-Id, also present in the body as request_id. Quote it: it is what lets us trace the exact call, with its internal context.