Skip to main content
Messaging and Platform failures return an error object, data: null, and a docs link to the matching section below. Branch on error.code; error.message is for people and can change.
error.type identifies the broad category. error.param names the affected request field, or is null when no field applies. A failed response does not always mean a write failed. For a timeout or uncertain dispatch, check completion before retrying to avoid duplicate sends. Error responses never include stack traces, database statements, or internal host names. Every error object includes request_id. It always equals the X-Request-Id response header, and browser clients can read it from the body. Include it when you contact support. To choose the ID yourself, send an X-Request-Id header of 1 to 128 letters, digits, ., _, :, or -, starting with a letter or digit. Polymorfa replaces any other value with a generated ID. request_log_url opens the request in the Console’s API request log. It is returned for requests made with a team API key or a project token, after the request is logged. The link opens the project’s log for a project token and the team view for a team key, and only members of that team can open it. It is omitted for client tokens, signed-in Console requests, and requests that fail authentication.

Rate-limit reasons

Every 429 response from the Messaging and Platform APIs includes a Polymorfa-RateLimit-Reason header. New values can be added; existing values are not renamed.

Codes added on September 18, 2026

These failures previously returned the generic code for their status. Handle both codes while you upgrade; a client that only reads the HTTP status needs changes only where the status changed. For BanSafe pacing responses, wait for the Retry-After response header before retrying. Never retry bansafe_send_outcome_unknown automatically. A bansafe_accounting_unavailable response means the message was not passed to WhatsApp; retry after its Retry-After interval without creating parallel attempts.

Official Number account errors

These official WhatsApp Business number failures previously returned the generic code for their status. Handle both codes while you upgrade.

BanSafe and Safe Mode codes

These stable error.code values identify a specific refusal. New values can be added, but existing values are not renamed or reused. See BanSafe, Restrictions, Safe Mode, and Warm-up plan. Project Health rules are described on the Safety page.

function-unavailable

503 · api_error Functions is unavailable in this environment.

function-runtime-unavailable

503 · api_error The Function runtime is unavailable. No invocation was admitted.

function-region-unavailable

503 · api_error Functions execution is unavailable in the selected region.

function-receipt-unavailable

503 · api_error The invocation result could not be recorded. Do not repeat it with a new key.

function-secret-decryption-unavailable

503 · api_error A pinned Function secret version cannot be decrypted.

function-invalid-input

400 · invalid_request_error Correct the Function request or configuration.

function-invalid-secret

400 · invalid_request_error Use a supported secret name and value without Polymorfa credentials.

function-build-failed

400 · invalid_request_error Provide valid self-contained JavaScript, TypeScript or visual actions.

function-forbidden

403 · permission_error Live Functions authority is required for this project.

function-region-mismatch

403 · permission_error The pinned deployment region does not match the invocation region.

function-not-found

404 · invalid_request_error The Function is unavailable to this caller.

function-deployment-not-found

404 · invalid_request_error The Function deployment is unavailable to this caller.

function-secret-not-found

404 · invalid_request_error The Function secret version is unavailable to this caller.

function-invocation-not-found

404 · invalid_request_error The Function invocation is unavailable to this caller.

function-revision-conflict

409 · conflict_error The Function revision changed. Refresh before saving.

function-idempotency-conflict

409 · conflict_error This Idempotency-Key is already bound to another Function request.

function-disabled

409 · conflict_error The Function is disabled. Enable it before invoking.

function-not-deployed

409 · conflict_error Promote a Function deployment or choose an immutable deployment.

function-secret-unavailable

409 · conflict_error A pinned secret version is unavailable or was revoked.

invalid-parameter

400 · invalid_request_error Correct the invalid request field. Check the field named by error.param against the method’s request schema. Correct the value before sending the request again.

invalid-credential

401 · authentication_error Supply a valid credential. Send the credential in the Authorization bearer header. Check its expiration and revocation status. Replace an expired or revoked credential.

entitlement-required

402 · permission_error The account needs the required entitlement for this action. Check the capability and billing requirements for this action in your account. For paid number service, check available credit and project billing priority. A payment-dispute hold requires support review even after another top-up. Resolve the restriction before resubmitting the request; automatic retries do not add credit or clear a hold.

gate-limit-reached

402 · permission_error A usage limit for this team or number was reached. Check the team or number limit named in the error message. For a Voice Automation asset limit, delete unused assets; for a monthly Voice Automation limit, wait for the next monthly period. Retrying without resolving the reported limit will fail.

method-not-allowed

405 · invalid_request_error Use a supported HTTP method for this resource. Use the HTTP method shown in the method reference.

permission-denied

403 · permission_error The credential does not have access to this resource. Check the credential’s team, project, resource access, and applicable client rules. A different resource identifier does not grant access.

missing-scope

403 · permission_error The credential lacks a required API scope. Use a credential with the scope named in the error message and method reference. Retrying with the same permissions will fail.

resource-not-found

404 · invalid_request_error The resource is unavailable to this caller. Check the resource identifier and the team or project bound to your credential. This response does not reveal whether a resource belongs to another account.

hms-not-enabled

404 · invalid_request_error Hosted message storage is not enabled for this Number.

media-fetch-failed

422 · invalid_request_error The supplied media could not be fetched. Supply a publicly accessible media URL. Check that the media URL returns the file directly and is reachable without cookies or authentication. Supply another URL or use the supported base64 input.

resource-gone

410 · invalid_request_error The requested retained resource has expired or was removed. The retained resource is no longer available. Request a new resource where the method supports it.

feature-unavailable

403 · permission_error This feature is not enabled for this team. The team is not enrolled in this feature, or it has been paused. Check the feature in your account before retrying. Retrying with the same team will fail.

stream-cursor-invalid

400 · invalid_request_error The resume cursor does not belong to this stream. Use a cursor received on a stream for the same project and the same types filter, or reconnect without a cursor.

stream-cursor-expired

410 · invalid_request_error The resume cursor is older than the stream retention window. Reconnect without a cursor to receive new events, and read the events you missed from the events API.

stream-connection-limit-reached

429 · rate_limit_error The team has reached its open event stream limit. Close an open event stream for this team, or wait for the delay in Retry-After before reconnecting.

state-conflict

409 · conflict_error The request conflicts with the resource state. Retrieve the resource to check its state, then choose an action valid for that state.

team-deletion-scheduled

409 · conflict_error The team is scheduled for deletion. It is read-only until an owner cancels deletion. A team owner scheduled the team for deletion. Until the deadline, the team accepts reads but refuses requests that change it, such as sending messages, creating API keys, launching campaigns or buying credits. An owner can cancel deletion in the console team settings to restore the team. Cancellation ends at the deadline; permanent deletion of the team and its credentials starts once nothing blocks it, such as a payment that is still settling.

hybrid-routing-paused

409 · conflict_error Hybrid sending is paused for this Number.

hybrid-choice-required

409 · conflict_error Choose which Hybrid Link connection to keep, or split the Number, before leaving Pro.

hybrid-transition-ineligible

409 · conflict_error This Hybrid Link change is unavailable for these Numbers.

hybrid-automation-unavailable

409 · conflict_error Conversation automation authority could not be established. No message was dispatched.

hybrid-transport-unavailable

409 · conflict_error The selected transport is unavailable for this message. No alternative transport was used.

hybrid-target-reference-unavailable

409 · conflict_error The message has no verified reference for this operation and transport.

send-outcome-unknown

409 · conflict_error A provider attempt may have executed. Read the operation status before sending again.

idempotency-conflict

409 · conflict_error This Idempotency-Key was already used with a different request. Use a new key for a different request. The key is bound to the first request’s method, path, body, Polymorfa-Version, and Prefer: respond-async choice for 24 hours. Send a new key for a new message or action.

idempotency-in-progress

409 · conflict_error A request with this Idempotency-Key is still in progress. Retry after Retry-After seconds to receive its outcome. Retry with the same key and the same request after the Retry-After delay. When the first request finishes, the retry returns its outcome.

idempotency-completed

409 · conflict_error A request with this Idempotency-Key already succeeded. It was not repeated. The first request with this key and request succeeded within the last 24 hours, and the write did not run again. Polymorfa does not keep the original response body. Read the result from message events, webhooks, or the resource instead of repeating the write. Audience create and the audience member and campaign recipient appends keep their result and return it on a retry instead; for audience create, this error means the audience from the first request was deleted.

idempotency-outcome-unknown

409 · conflict_error The outcome of the request with this Idempotency-Key was not recorded. It was not repeated; check completion before using a new key. The first request with this key started but its outcome was not recorded, so it might have taken effect. The key stays unusable for 24 hours after the first request. Check message events or the resource, and send a new key only after you confirm that the write did not happen.

call-claimed

409 · conflict_error Another participant claimed this call. Another participant answered the call exclusively. Stop attaching media to this call; your open connections are closed.

call-not-ringing

409 · conflict_error The call is no longer ringing. The call was already answered, declined, or ended. Wait for its lifecycle event instead of declining it again.

connection-limit

409 · conflict_error The call has reached its connection limit. Leave an unused connection of this call with POST /messaging/voip/calls/{id}/leave, then attach the new connection.

unsupported-for-connection

409 · conflict_error The session’s connection does not support this call operation. Check the Number’s connection. Cloud API Numbers place and receive one-to-one audio calls; use a linked-device Number for video or group calls.

call-permission-required

403 · permission_error The recipient has not granted this business permission to call them. Ask the recipient to grant your business call permission, for example by sending a call permission request, then place the call again.

invalid-sip-trunk

400 · invalid_request_error The SIP trunk cannot receive calls for this session. Use the ID of a SIP trunk in the session’s project whose direction is outbound or both, or set inboundRoute to clients.

calls-disabled

403 · permission_error Calling is turned off for this number. Calling is turned off in the Number’s call settings. Set callsEnabled to true, or use another Number.

call-recipient-opted-out

403 · permission_error The recipient is on the team’s do-not-call list. The recipient is on your team’s do-not-call list. Do not call them. Remove the entry only if they asked to be called again.

call-destination-blocked

403 · permission_error The team does not allow calls to this destination. Your team’s call policy blocks the recipient’s country calling code. When the team blocks any code, a recipient without a known phone number is also refused. Change the blocked country codes, or call the recipient by phone number.

call-permission-request-limited

429 · rate_limit_error WhatsApp limits how often this number can ask this person for call permission. Follow Retry-After when supplied. WhatsApp allows one call permission request per person every 24 hours and two every 7 days; a connected call resets the limits. Wait for Retry-After when supplied, or read the limits from the call permission.

call-permission-granted

409 · conflict_error The person already granted this number permanent call permission. The person already granted this Number permanent call permission. Place the call instead of asking again.

call-opt-out-limit

409 · conflict_error The team’s do-not-call list is full. The do-not-call list holds at most 100,000 entries. Remove entries you no longer need before adding more.

number-restricted

403 · permission_error WhatsApp restricts this number to calling people it has already chatted with. The restriction lifts on its own; follow Retry-After when supplied.

sip-trunk-in-use

409 · conflict_error A session still sends incoming calls to this SIP trunk. Change the call settings of every session that routes incoming calls to this trunk, then delete the trunk again.

sip-trunk-revision-conflict

409 · conflict_error The SIP trunk changed since it was read. Retrieve the SIP trunk, apply your change to its current state, and send its current revision as expectedRevision.

sip-trunk-limit

409 · conflict_error The project has reached its SIP trunk limit. Delete a SIP trunk you no longer use, or create the trunk in another project.

sip-unavailable

503 · api_error SIP trunks are not available. SIP trunks are not enabled for this deployment. Repeating the request will fail until they are.

voice-not-enabled

403 · permission_error The Voice Automation beta is not enabled for this team. Enroll the team in the Voice Automation beta, then send the request again. Reading and deleting existing audio assets and provider credentials stays available without it.

provider-credential-invalid

422 · invalid_request_error The voice provider rejected the key. The provider refused the key. Check that it is active, has text-to-speech permission and has quota, then store a new key or run verification again.

provider-unavailable

503 · upstream_error The voice provider is not available. The provider did not answer, or Polymorfa has no managed key for it. Retry later with backoff, or use your own provider key with credentialId.

asset-not-ready

409 · conflict_error The audio asset is not ready. Wait until the audio asset status is ready. Watch the voice.asset_ready webhook or retrieve the asset.

voice-asset-in-use

409 · conflict_error A campaign or flow uses this audio asset. Remove the asset from every campaign and flow that uses it, then delete it again.

voice-asset-revision-conflict

409 · conflict_error The audio asset changed since it was read. Retrieve the audio asset, apply your change to its current state, and send its current revision as expectedRevision.

voice-unavailable

503 · api_error Voice Automation storage is not available. Voice Automation audio storage or key protection is not configured for this deployment. Repeating the request will fail until it is.

rate-limit-exceeded

429 · rate_limit_error The request limit was reached. Follow Retry-After when supplied. Wait for the delay in Retry-After when supplied. Reduce concurrent requests and use bounded backoff. The Polymorfa-RateLimit-Reason header names the limit.

internal-error

500 · api_error An unexpected service failure occurred. Keep the request ID for support. Keep error.request_id and contact support if the failure persists. Check whether a write completed before repeating it.

operation-not-supported

501 · invalid_request_error This operation is not supported. Check the method’s supported connection types. Repeating the same action on an unsupported connection will fail.

upstream-failure

502 · upstream_error The messaging provider could not complete the request. The messaging provider did not complete the request. Check the session and the operation’s outcome before repeating a write.

service-unavailable

503 · api_error A required service is unavailable. Check completion before repeating a write. Wait for the service to recover. For a write, check completion before trying again.

credential-verification-unavailable

503 · api_error Credential verification is temporarily unavailable. You do not need to replace your credential. Credential verification could not complete. Wait and retry; this response does not mean your credential is invalid.

session-not-ready

503 · conflict_error The session is not connected. Reconnect it before trying again. Retrieve the session and reconnect or pair it before repeating the action. A linked-device number that disconnects while a message is being sent returns this code.

command-dispatch-failed

503 · api_error Command dispatch could not be confirmed. Check completion before repeating a write. Dispatch was not confirmed. The action could still have been accepted. Check its outcome before repeating a write.

result-unknown

504 · api_error The result was not obtained before the deadline. Check completion before repeating a write. The response deadline expired before the result was known. The action might have completed. Check its outcome or correlated event before sending it again.

parent-bsuid-not-supported

400 · invalid_request_error Parent business-scoped user IDs cannot be used here. Use the person’s business-scoped user ID. A parent business-scoped user ID (CC.ENT. followed by an identifier) identifies a person across several business portfolios. Polymorfa does not send messages or block people by it. Use the bsuid value from the person’s events, or their conversation id, instead. error.param names the field when the request supplied it.

recipient-not-on-whatsapp

400 · invalid_request_error The recipient does not have a WhatsApp account. WhatsApp reported the recipient as undeliverable: the number has no WhatsApp account, or the recipient’s app cannot receive the message. Check the number and its country code. Repeating the same send fails. Official WhatsApp Business numbers return this code.

conversation-window-closed

400 · invalid_request_error The customer service window is closed. Send an approved template to reopen the conversation. More than 24 hours have passed since the customer last messaged or called this number. Send an approved template instead. The customer service window reopens when the customer replies. Official WhatsApp Business numbers return this code, either from WhatsApp or, for teams in the customer service window beta, before the message is sent. Graph API clients receive WhatsApp error code 131047.

template-not-approved

400 · invalid_request_error The template is not approved for sending in this language. The template does not exist in the requested language, or WhatsApp paused or disabled it. Check the template’s status and language, then send an approved template. Official WhatsApp Business numbers return this code.

media-too-large

413 · invalid_request_error The supplied media exceeds the size limit. Media sent by URL or base64 is limited to 50 MB. error.param names the media field. Compress the file or send a smaller one.

whatsapp-rate-limited

429 · rate_limit_error WhatsApp is limiting requests from this number. Follow Retry-After when supplied. WhatsApp limited this number. Wait for Retry-After when supplied, then retry with backoff and fewer concurrent sends. Retrying immediately extends the limit.

new-chat-limit-reached

429 · rate_limit_error WhatsApp limited how many new chats this number can start. This linked-device number cannot start more new chats until WhatsApp’s cycle resets. Polymorfa refuses the send before it reaches WhatsApp while the number is capped, and WhatsApp returns the same code when it rejects a send itself. Messages to people who already have a chat with this number are not affected. Wait for Retry-After when supplied, or read the number’s cap from Get session. See WhatsApp new-chat cap.

marketing-disabled-on-cloud-api

403 · permission_error This WhatsApp Business Account refuses Marketing templates sent as ordinary messages. Turn the setting off in WhatsApp or send through Marketing Messages. WhatsApp error 131063: the WhatsApp Business Account has disable_marketing_messages_on_cloud_api turned on, so it refuses Marketing templates sent as ordinary messages. Nothing was sent. Turn the setting off for the account in WhatsApp, or send the template through the Marketing Messages API. See Meta’s Marketing Messages guide.

whatsapp-account-restricted

403 · permission_error WhatsApp restricted this number from sending this message. WhatsApp restricted this number. A linked-device number returns this code when WhatsApp blocks it from messaging people it has no chat with; an official WhatsApp Business number returns it when its account is locked. Check the number’s status in the Safety page or WhatsApp Manager before sending again.

whatsapp-authorization-required

401 · authentication_error Meta no longer accepts this number’s authorization. Renew it before sending again. Meta rejected the access token saved for this official WhatsApp Business number. Your Polymorfa credential is not affected. Renew the number’s Meta authorization with a reauthorization QuickLink, then send again.

whatsapp-payment-method-required

402 · permission_error Meta reported a payment method problem on this WhatsApp Business Account. Meta reported a problem with the payment method of this number’s WhatsApp Business Account, such as a missing, inactive or over-limit credit line. Add or fix the payment method in WhatsApp Manager under Overview, then send again. Official WhatsApp Business numbers return this code.

whatsapp-number-not-registered

409 · conflict_error Meta reports that this number is not registered on the WhatsApp Business Platform. Meta reports that this official WhatsApp Business number is not registered on the WhatsApp Business Platform. Check the number’s status in WhatsApp Manager and reconnect it before sending again.

bansafe-suspended

403 · permission_error Polymorfa suspended sending from this number. Resolve the open findings on the number. The restriction reviews itself once the number sends cleanly again.

bansafe-org-suspended

403 · permission_error Sending is suspended for every number in this team. Contact support. Only Polymorfa can remove a workspace suspension.

bansafe-cold-blocked

403 · permission_error First messages to people who have not written to this number are paused. Message people who wrote first, or send the outreach through Campaigns on Pro. A group add has no Campaigns route.

bansafe-cold-held

409 · conflict_error The campaign recipient was held because they never wrote to this number first. Set the campaign’s cold-send policy, or import contacts who opted in.

bansafe-throttled

429 · rate_limit_error This number is paced while it recovers. Follow Retry-After. Wait for Retry-After, slow down, or move the traffic into Campaigns.

bansafe-daily-allowance-reached

429 · rate_limit_error This number used its warm-up allowance for the day. Follow Retry-After. Wait for Retry-After, raise the project’s warm-up settings, or send through Campaigns.

bansafe-accounting-unavailable

503 · api_error The message was not sent because its allowance could not be authorized. Follow Retry-After. The message was not passed to WhatsApp. Wait for Retry-After, then retry once. Do not create parallel retries.

bansafe-send-outcome-unknown

409 · conflict_error This send was already reserved by another attempt. Do not retry it automatically. Do not retry automatically. Reconcile delivery state before deciding whether to send a new message.

campaigns-not-entitled

402 · permission_error This number’s plan does not include Campaigns. Move the number to a plan that includes Campaigns.

campaign-throughput-capped

400 · invalid_request_error The requested campaign throughput is above the safety ceiling. Lower the rate or daily cap. Lower the requested rate, hourly cap, or daily cap to the ceiling named in error.param.

campaign-approval-required

409 · conflict_error This request needs approval from a team owner or admin. Nothing was sent. Ask a team owner or admin to approve the pending request in the console. See Require approval for large sends.

campaign-approval-stale

409 · conflict_error The campaign changed or the approval request is closed. Nothing was sent. Launch again to request a new approval.

campaign-variables-missing

422 · invalid_request_error A recipient has no value and no fallback for a variable in the campaign content. Give each variable named in the message a fallback in variableMapping, map it to a recipient variable that has values, or fix the audience. To launch anyway, send skipMissingVariables: true; those recipients are skipped with missing_variable.

hybrid-group-linked-devices-unavailable

409 · conflict_error A Hybrid Number’s linked-device connection is unavailable for a group operation. Reconnect that connection before trying again. The request did not fall back to Official API. Existing funding and account restrictions still apply.

Meta-compatible errors

Meta-compatible routes retain the Meta error envelope. Use its numeric error.code, error_subcode when present, and fbtrace_id for correlation. The native error object above does not replace that contract.