API error codes
Every error response uses the v1 envelope: object, code, message, and request_id. Each code includes a stable docs_url pointing here.
Error catalog
| Code | HTTP | Retryable | Meaning | Docs |
|---|---|---|---|---|
| capability_not_supported | 400 | no | The sender phone number does not support the required channel capability (SMS or MMS) for this request. | Docs |
| sender_inactive | 400 | no | The sender phone number exists but is not active/sendable. | Docs |
| validation_failed | 400 | no | Request body or query parameters failed validation. Inspect `details` for per-field errors. | Docs |
| missing_api_key | 401 | no | No API key was supplied. Send `Authorization: Bearer <key>` or `X-Integration-Key`. | Docs |
| billing_failed | 402 | yes | Chargebee billing for the premium number addon failed. The purchase was not completed. | Docs |
| billing_required | 402 | no | A payment method or billing setup is required before purchasing premium numbers. | Docs |
| feature_not_enabled | 403 | no | A required product feature flag is disabled for this organization (for example media/MMS uploads). Enable the feature or contact support. | Docs |
| insufficient_scope | 403 | no | The key authenticated successfully but does not hold the scope required for this endpoint. | Docs |
| invalid_api_key | 403 | no | The supplied key is unknown, revoked, or expired. | Docs |
| production_not_ready | 403 | no | The organization is not production-ready for live API Portal sending (for example missing approved 10DLC or billing). Complete API Portal onboarding, or use a platform-entitled organization. | Docs |
| scope_invalid | 403 | no | The key's scope_level does not permit this resource. Personal keys cannot access organization-only resources (DNC, org-level usage, raw org number lists), and organization keys must be issued by a user who still holds the owner role. | Docs |
| sender_not_assigned | 403 | no | Personal keys may only send from numbers assigned to the acting user (or shared sandbox numbers in test mode). | Docs |
| invalid_sender | 404 | no | The requested sender phone number was not found, is not visible to this key, or cannot be used in this environment (for example a non-sandbox number on a test key). | Docs |
| no_default_sender | 404 | no | No valid default sender could be selected for this key/scope. Assign an active number or pass an explicit from / from_phone_number_id. | Docs |
| not_found | 404 | no | Resource not found, or visible only to a different organization. Cross-tenant access never returns 200 or 403. | Docs |
| ambiguous_contact | 409 | no | Multiple contacts share the same phone number. Do not guess — ask which contact to use. | Docs |
| idempotency_in_progress | 409 | yes | A request with the same `Idempotency-Key` is already in flight. Retry shortly. | Docs |
| idempotency_key_reused | 409 | no | The same `Idempotency-Key` was reused with a different request body. Use a fresh key for distinct requests. | Docs |
| operation_in_progress | 409 | yes | An operation for this number is already in progress. Poll the operation until it reaches a terminal state before retrying. | Docs |
| action_required | 422 | no | The operation cannot proceed automatically. Inspect `action_required` on the operation object and retry with the appropriate parameters. | Docs |
| approval_required | 422 | no | Organization is not yet approved for messaging. Complete onboarding/registration before sending. | Docs |
| budget_exceeded | 422 | no | Rotation or purchase budget limit has been reached for this organization or number. Try again later. | Docs |
| campaign_not_configured | 422 | no | No compliance campaign binding is configured for this client. Premium numbers cannot be searched or purchased until binding is complete. | Docs |
| charset_security_evasion | 422 | no | Message body contains mixed-script or lookalike Unicode characters that carriers treat as security evasion. Resubmit using the provided normalized_text (standard Latin characters only). | Docs |
| cleanup_required | 422 | no | A purchase step failed and automatic compensation did not fully clean up carrier inventory. The number is not active; support must reconcile. | Docs |
| compliance_blocked | 422 | no | Send blocked by compliance policy (illegal words, org policy, or similar). | Docs |
| dnc_blocked | 422 | no | Recipient is blocked by DNC settings; the send was not enqueued. | Docs |
| insufficient_credits | 422 | no | Credit balance is too low to cover this send. Top up before retrying. | Docs |
| inventory_unavailable | 422 | yes | No available numbers were found in the requested area code. Try a different area code. | Docs |
| media_fetch_failed | 422 | no | Media could not be fetched or validated for MMS. Check the URL or re-upload via upload_media. | Docs |
| offer_expired | 422 | no | The premium number offer has expired or is no longer available. Search again for a fresh offer. | Docs |
| opted_out | 422 | no | Recipient has opted out (replied STOP). The send cannot complete. | Docs |
| premium_number_locked | 422 | no | This number is in a cooldown period from a recent operation and cannot be rotated until the lock expires. | Docs |
| quiet_hours_blocked | 422 | no | Send blocked by quiet-hours policy for the recipient timezone. | Docs |
| rate_limited | 429 | yes | Per-IP or per-key rate limit exceeded. Honor the `Retry-After` header before retrying. | Docs |
| internal_error | 500 | no | Unexpected server error. Do not tight-loop retry; use exponential backoff if you retry at all, and contact support with the `request_id` if it persists. | Docs |
| provider_unavailable | 503 | yes | The messaging carrier is temporarily unavailable. Retry with the same Idempotency-Key. | Docs |
