MsgBubblesDocs

Errors & limits

Every error has the same shape:

{ "error": "invalid_from_handle", "message": "from_handle is not a number assigned to your account", "request_id": "req_…" }

error is a stable machine-readable code (branch on this, not the HTTP status or the human message); message is human-readable and may change. request_id is on every response — success or error — and is mirrored by the X-Request-Id header; quote it when reporting a problem. A 5xx never includes internal detail.

Common codes

StatusCodeMeaning
400invalid_requestThe request body, query, or path failed validation — a missing, unknown, or malformed field.
400invalid_handleto / from_handle is not a valid E.164 number or iMessage email.
400invalid_from_handleThe from number is not assigned to your account (or has no connected WhatsApp session when channel is forced).
400invalid_attachmentsAn attachment_id is unknown or already used by another message.
400invalid_urlA webhook url isn’t a public http(s) endpoint (private, loopback, or link-local addresses are rejected).
401unauthorizedMissing or invalid API key.
403forbiddenValid key, inactive account.
404not_foundThe resource doesn’t exist — or belongs to a different account.
409conflict, not_a_groupThe action doesn’t apply: editing an SMS, reacting before delivery, group ops on a DM, retrying a non-failed message.
429rate_limitedRate limit exceeded; retry after the window resets.
502 / 503*_failed, device_offline, unavailableA synchronous upstream action failed or the sending number is temporarily offline. Safe to retry.

Rate limits

  • API requests are limited per key (default 120 requests/minute). Exceeding it returns 429.
  • Outbound message throughput is additionally paced per sending number to protect deliverability — bursts queue rather than fail, so a 202 means the message will go out as capacity allows.

Retries

  • Always send with an Idempotency-Key so network-level retries can’t double-send.
  • 5xx responses and 429 are safe to retry with backoff. 4xx (other than 429) are not — fix the request.