Errors

Every error has the same shape and a stable code to branch on.

The error object

{
  "error": {
    "code": "validation_error",
    "message": "Check these fields: content.text.",
    "details": { "fields": ["content.text"] }
  }
}

Branch on code, never on message, which may change. provider_code is Meta's own number and details holds what you can act on, such as details.fields for a validation error. Both appear only when there is something to say.

Codes

StatusCodes
400idempotency_key_required, invalid_cursor
401unauthorized
403insufficient_scope, forbidden
404not_found
409idempotency_conflict, idempotency_in_progress, channel_disconnected, customer_id_taken, contact_deleted, tag_exists
422validation_error, window_closed, contact_blocked, media_invalid, template_invalid, customer_id_invalid
503unavailable

Failed sends

A send that Meta refuses after the 202 does not come back as an HTTP error. The message turns rejected or failed and its error holds the code. Omnio retries only rate limits and Meta outages, up to five tries.

Meta codeerror.codeRetried
131047window_closedNo, send a template
131026undeliverableNo
131056recipient_rate_limitedYes
130429throughput_exceededYes
131048spam_rate_limitedNo
132000, 132001template_invalidNo
131053media_errorNo
190channel_disconnectedNo, sends wait until the channel reconnects

Any other Meta code reads meta_ followed by the number.

Rate limits

Omnio does not rate limit API keys today. WhatsApp paces each number, so Omnio queues sends and spaces them out for you.

NextWebhooks