Skip to content

Error codes

Every error response carries its code in the error field. Base your logic on the code, which is stable; supporting text may change. Some errors carry extra fields, such as required_scope, details or the Retry-After header.

{
"error": "insufficient_scope",
"required_scope": "messages:send"
}

Each endpoint page lists the errors of that route. This page gathers all of them in one place.

400: invalid request

StatusCodeWhat it means and what to do
400invalid_jsonThe body is not valid JSON. Check the syntax and the Content-Type: application/json header.
400invalid_requestThe request contains a null character (%00 in the URL or \u0000 in the body), which is never valid. Remove it from the value you send.
400invalid_phone_numberThe phone number is not valid. Send it with the country code, such as +5511988887777.
400invalid_recipientThe recipient given in to could not be found.
400contact_not_foundThe contact_id given in to does not belong to the account.
400contacts_not_enabledSending by contact_id is unavailable right now. Try again later.
400groups_not_enabledGroup features are unavailable right now. Try again later.
400not_group_memberThe number is no longer a member of the given group.
400invalid_message_idThe message identifier is not in the msg_… format.
400invalid_contact_idThe contact identifier is not in the ct_… format.
400invalid_group_idThe group identifier is not in the grp_… format.
400invalid_event_idThe event identifier is not in the evt_… format.
400invalid_request_idThe request identifier is not in the req_… format.
400invalid_organization_idThe organization identifier is not in the org_… format.
400invalid_idempotency_keyThe Idempotency-Key header is empty or longer than 255 characters. See Sending without duplicates.
400invalid_cursorThe pagination cursor is invalid. Use the value returned by the previous page, with the same filters.
400invalid_number_idThe number identifier starts with num_ but is not num_ followed by 32 characters.
400invalid_aliasThe alias is not valid. It starts with a letter and has up to 50 characters.
400reserved_aliasThe alias main, and any alias that starts with num_, are reserved.
400no_changesThe update changes nothing. Send at least one field with a new value.
400not_pending_deletionThe number has no scheduled removal to cancel.
400message_not_editableThe message can no longer be edited, or the body does not fit it. Only text messages, calendar events and the caption of an image, video or document can be edited. See Edit and delete.
400edit_window_expiredA text or a caption can only be changed within 15 minutes of sending it. Send a new message. See Edit and delete.
400message_not_calendarThe message is not a calendar event, so it has no responses to list. See Get event responses.
400message_not_deletableThe message can no longer be deleted.
400no_payment_methodThe account has no payment method on file. Add one in the dashboard.

401: not authenticated

StatusCodeWhat it means and what to do
401not_authenticatedThe key is missing, malformed, unknown, revoked or expired. Check the Authorization: Bearer YOUR_KEY header and see API key. Retrying with the same key does not help. On the MCP server the same code also answers a streaming connection opened without a key. Send the Authorization header on the connection or, if your client supports sign-in, sign in with your account.

402: plan, quota or payment

StatusCodeWhat it means and what to do
402feature_not_availableThe current plan does not include the feature (for example extra numbers or sending to groups). See Quota and usage.
402subscription_inactiveThe subscription is not active (details.status says why). Sort it out under Billing in the dashboard.
402contact_quota_exceededThe number’s contact quota for the cycle is used up. It resets when the cycle turns.
402extra_numbers_limit_reachedThe account reached the plan’s maximum of extra numbers (details.limit).
402payment_declinedThe card declined the charge. Nothing was created, or the cancelation of a number’s scheduled removal, which stays scheduled. Update the payment method.
402payment_requires_authenticationThe card requires extra authentication and cannot be charged automatically. Nothing was created, or the cancelation of a number’s scheduled removal, which stays scheduled.

403: not allowed

The key was accepted, but the operation is not allowed: the key lacks a scope, or the operation does not apply to this number.

StatusCodeWhat it means and what to do
403insufficient_scopeThe key lacks the route’s scope (required_scope names it).
403main_number_pair_not_allowedThe main number is paired only from the dashboard.
403main_number_update_not_allowedThe operation applies only to extra numbers, not to main.
403no_device_linkThe extra number has not been paired yet. Pair it before connecting.
403extra_number_not_pairedThe extra number lost its pairing. Pair it again.

404: not found

StatusCodeWhat it means and what to do
404not_foundThe resource does not exist in the account.
404number_not_foundThe alias or the id (num_…) in the URL does not match any number of the account.
404no_main_numberThe main number has not been connected yet, so GET /v1/numbers/main has nothing to show. Connect it in the dashboard.
404message_not_foundThe message the request refers to (the one to quote, react to, edit or delete) could not be found on this number while the request was processed. Read the message with GET and, if it exists, try again using the number_id of the number that owns it.
404contact_not_foundThe contact does not exist on this number. A contact_id that belongs to another number answers this way. See List messages.
404group_not_foundThe group does not exist on this number. A group_id that belongs to another number answers this way. See List messages.
404organization_not_foundThe organization does not exist or is not your key’s.
404request_not_foundThe given request_id does not match a known request.
404contact_picture_unavailableThe contact’s picture is not available. See Profile picture.
404group_picture_unavailableThe group’s picture is not available. See Group picture.

409: conflict with the current state

StatusCodeWhat it means and what to do
409number_not_connectedThe number that has to act is not connected to WhatsApp. Reconnect it and try again.
409already_connectedThe number is already connected. Nothing to do.
409already_connectingThe connection is already in progress. Wait for it.
409already_disconnectedThe number is already disconnected. Nothing to do.
409already_paired_or_connectedThe number is already paired or connected.
409not_pairingThere is no pairing in progress to cancel (or the phone just completed it).
409number_already_existsThe alias or the phone number is already registered in the account.
409alias_already_existsAnother number of the account already uses that alias.
409activation_already_in_progressAnother creation of the same number is being charged right now. Wait for its result.

422: data that fails validation

StatusCodeWhat it means and what to do
422validation_errorA field is missing, malformed or out of range. details.errors says which.
422sender_not_foundThe given sender does not match any number of the account.
422group_not_owned_by_numberThe group belongs to another number of the account, not to the alias in the URL.
422message_not_replyableThe quoted message has not reached WhatsApp yet or was deleted.
422message_not_reactableThe message has not reached WhatsApp yet or was deleted.
422no_main_number_configuredThe main number has not been connected yet. Connect it from the dashboard.
422main_number_not_pairedThe main number lost its pairing. Connect it again from the dashboard.

429: rate limits and message quota

All of them carry the Retry-After header when there is a known waiting time. Wait that long instead of retrying right away.

StatusCodeWhat it means and what to do
429rate_limit_exceededToo many requests in a short time (including MCP server calls).
429number_creation_rate_limitedThe account created extra numbers faster than allowed. Nothing was charged. See Add.
429send_rate_spacingThe send came before the number’s minimum interval between messages. See Rate limits.
429messages_quota_exceededThe number’s message quota for the cycle is used up. It resets when the cycle turns.
429messages_per_minute_limit_exceededThe number went over its messages-per-minute limit.
429recipients_per_day_limit_exceededThe number went over the daily limit of messages to the same recipient.
429warmup_limit_exceededThe number is new and still warming up, with a lower daily volume.
429duplicate_burst_blockedThe same message was sent to too many recipients in a row.
429reply_ratio_too_lowThe number sends far more messages than it gets replies. Wait for replies before sending more.
429refresh_rate_limitedToo many contact refreshes per minute.
429pairing_rate_limitedToo many pairing requests (code or QR code). See Pairing with the API.
429too_many_streamsMCP server: too many open streaming connections for the key or the source address.

500, 502 and 503: failure on our side

StatusCodeWhat it means and what to do
500internal_errorUnexpected error. Try again; if it persists, contact support.
502integration_errorAn outside service the operation depends on (for example, the payment processor when you add an extra number) answered with an error. Try again in a moment; if it persists, contact support.
503payment_gateway_unavailableThe charge could not be confirmed in time. Nothing was created, or the cancelation of a number’s scheduled removal, which stays scheduled. Try again.
503service_unavailableA service the API depends on is unavailable, or the API key or the account’s plan could not be checked right now. Nothing was done and nothing is wrong with the key: try again in a moment.

Message failures

A message accepted with 202 can fail later, on WhatsApp. In that case its status becomes failed and the error object carries code, message and, when there is guidance, hint. The same object arrives in message.*.failed events. See Message status.

CodeWhat it means and what to do
number_not_connectedThe number was not connected when the message was sent. Reconnect it and send again.
message_timeoutWhatsApp did not confirm the send in time. The message may have gone out: check before resending.
whatsapp_send_failedWhatsApp refused the message. See error.message.
media_fetch_failedThe media could not be downloaded from the URL. It must be public and reachable.
media_too_largeThe media exceeds the maximum size for its type. See Send media.
unsupported_media_formatThe file format is not accepted for that media type (including a file that is not media, or a sticker that is not a 512×512 WebP). The hint says which format is expected.
invalid_cta_url_payloadThe link-button message arrived without the button’s address. Add the URL and send again.
invalid_interactive_typeOnly interactive messages with a link button are accepted.
internal_errorThe platform could not process the send. Send again; if it persists, contact support.
reaction_lid_unavailableWhatsApp did not allow a reaction to that contact just now. Try again later.
reaction_send_failedWhatsApp did not accept the reaction (message.react.failed event). Try again.
edit_failedWhatsApp refused the edit (message.edit.failed event), for example a calendar event WhatsApp no longer accepts changing. A text or a caption outside the 15 minutes never reaches WhatsApp: the API answers 400 edit_window_expired.
message_secret_unavailableThis number can no longer change the calendar event, for example because it was linked again after the event was sent (message.edit.failed event). Send a new event.
calendar_edit_unavailableThe platform cannot change or cancel calendar events at the moment (message.edit.failed event). The failure does not depend on your request and repeating it does not help. Send a new event with the new details.
delete_failedWhatsApp refused to delete the message (message.delete.failed event).

New codes may appear. Treat an unknown code as a permanent failure and log error.message.

MCP server errors

When an MCP tool cannot do what was asked, the agent receives the API code in the tool result itself, as kind: code (for example conflict: number_not_connected or rate_limited: messages_quota_exceeded). The codes are the ones on this page. See MCP server: Errors.