Errors

Bird returns a single error envelope on every failed request.

The error envelope

{
  "type": "rate_limited",
  "message": "Too many requests. Retry after 1.0s.",
  "doc_url": "https://bird.dev/docs/errors#rate_limited",
  "request_id": "req_3nB91x..."
}

type is drawn from a closed union — new types are added; existing types are never renamed. Branch on type, never on message. Quote request_id in any support request.

HTTP status code mapping

CodeMeaning
400Malformed request — missing required field, bad JSON, unknown parameter.
401Authentication failed — key missing, malformed, or revoked.
403Authenticated but not authorized — scope, sender, region, or missing User-Agent.
404Resource not found, or your key can't see it.
409State conflict — usually an idempotency key reused with a different payload.
422Validation failed — shape is correct, values are not.
429Rate limited — back off and honor Retry-After.
5xxBird's problem. Retry with backoff; we're already paged.

Error type registry

typeHTTPMeaningWhat to do
invalid_request400Body is malformed JSON or contains unknown parameters.Fix the request shape.
invalid_recipient422Recipient format is wrong for the channel.Use RFC-5322 for email, E.164 for SMS, voice, WhatsApp.
missing_required_field400A required field is absent.The param field on the envelope names the missing field.
authentication_failed401Key missing, malformed, or revoked.Check the prefix matches the environment and the key is current.
permission_denied403Key lacks the required scope, sender, or IP allowlist entry.Issue a key with the scope named in param, or update allowlist.
not_found404Resource ID doesn't resolve under this key.Confirm the ID prefix and that the key has read access.
conflict409Resource is in a state that disallows this transition.Inspect the resource's current state.
idempotency_key_in_use409Same Idempotency-Key is in flight on another request.Retry after a moment; the in-flight request will complete.
rate_limited429Over the per-team rate.Honor Retry-After (seconds). Safe to retry.
quota_exceeded429Account-level monthly cap reached.Contact support to lift the cap.
template_not_approved422WhatsApp template hasn't been approved by Meta.Wait for approval, or fix and resubmit.
session_window_expired422WhatsApp free-form send outside the 24-hour session window.Send an approved template instead.
sender_not_verified403from isn't a verified sender on this account.Verify the domain or number in the dashboard.
carrier_rejected424Carrier rejected the send for content or recipient reasons.Check carrier_trace. Sometimes retryable.
recipient_unsubscribed422Recipient is on your suppression list.Do not send. This is the system working.
internal_error500Unexpected failure on our side.Retry with backoff. We're already paged.
service_unavailable503Upstream dependency (carrier, Meta) is degraded.Retry with backoff.

Retry guidance

Safe to retry with exponential backoff:

  • rate_limited — honor Retry-After first
  • internal_error
  • service_unavailable
  • carrier_rejected (sometimes — inspect carrier_trace first)

Do not retry — the request will fail the same way:

  • invalid_request, invalid_recipient, missing_required_field
  • permission_denied, authentication_failed
  • recipient_unsubscribed, sender_not_verified
  • template_not_approved, session_window_expired

Pair retries with an Idempotency-Key so duplicates don't double-send.

Idempotency keys + retries

Every POST accepts an Idempotency-Key header. Replays within 24 hours return the original response with Idempotency-Replayed: true, so retrying after a network blip is safe. Reusing the same key with a different payload returns 409 idempotency_key_in_use and the conflicting_fields array tells you which fields differed.

Empieza con un canal.
Añade los demás cuando estés listo.

Una clave API de prueba es tuya de inmediato. El acceso a producción se desbloquea cuando añades un método de pago y verificas un remitente.

ComenzarLeer documentacióno

¿Usas Claude Code, Cursor o Codex? Apúntalos a nuestro servidor MCP — 141 herramientas, una por endpoint de API, con claves de agente con permisos limitados.