waiaconnect

Documentação / Completo

O catálogo completo de erros

Markdown

Todos os code que /v1 emite, com o seu HTTP e o que fazer. São estáveis: desde o primeiro integrador NÃO são renomeados (quebrariam o seu switch). Só em inglês, de propósito (o code é o contrato, a message é para colar num log e buscar no Google).

⚠ Há dois catálogos diferentes. Este são os erros HTTP (o envelope { error: { code } }, a resposta imediata). Uma mensagem que o WhatsApp recusa DEPOIS do 202 não aparece aqui: o motivo dela viaja em lastErrorCode quando você consulta o estado da mensagem (WINDOW_24H_EXPIRED, RECIPIENT_OPTED_OUT, …). Estão no openapi em Message failure codes.

codeHTTPmessageação
API_KEY_MISSING401The Authorization header is missing or malformedBug in your integration — send Authorization: Bearer wc_live_…
API_KEY_INVALID401The API key is invalid or has been revokedCheck / rotate the key in the panel
ACCOUNT_SUSPENDED403Account is suspended or cancelledResolve billing / contact support
RATE_LIMITED429Per-key rate limit exceededBack off and retry (limit 600/min per key)
IDEMPOTENCY_KEY_REQUIRED400The Idempotency-Key header is requiredSend a unique UUID in Idempotency-Key
INVALID_TYPE400type must be text, template, image, document, audio or videoFix type
INVALID_BODY400text.body (or template.name) is requiredFix the message body
INVALID_RECIPIENT400to must be a plausible E.164 number (8–15 digits)Fix to
AUDIO_CAPTION_NOT_ALLOWED400type audio does not accept a captionRemove audio.caption
CONNECTION_REQUIRED400Provide connectionId (conn_…) or from (phoneNumberId)Send one of them
CONNECTION_NOT_FOUND404No connection matches connectionId/from for this accountCheck the connection id (a number of ANOTHER account is also reported as not found)
CONNECTION_NOT_READY409The number exists but is not connected yet (details.status = its real state)Wait for it to become connected, or refresh its status in the panel — do NOT change your payload
MESSAGE_NOT_FOUND404No message with that id for this accountCheck the msg_… id
INVALID_MESSAGE_ID400messageId is not a WhatsApp message id (a wamid.…) — e.g. a msg_… of a message you sentSend data.message.id of message.received as messageId in the body
INVALID_TYPING400typing must be true, false or omittedFix the body
INBOUND_MESSAGE_NOT_FOUND404No received message with that id for this account (unknown, of another account, or older than 30 days)Check the id; a message of ANOTHER account is also reported as not found
MESSAGE_NOT_INBOUND409The id is a message sent FROM your number (by the API or the phone)Only received messages can be marked as read
MESSAGE_TOO_OLD410The message was received more than 30 days ago — Meta does not mark itNothing to do; mark messages when you read them
MESSAGE_READ_REJECTED422Meta did not accept the read (details.metaCode)Check the id came from this number's message.received; do not retry unchanged
META_UNAVAILABLE502Meta did not answer (network or 5xx)Retry in a few seconds
QUOTA_EXCEEDED429Plan message quota exceeded (policy block)Upgrade plan or wait for the period to renew
MEDIA_ID_REQUIRED400A media id is requiredInclude the media id in the path
MEDIA_NOT_FOUND404No media with that id for this account (or expired at Meta)Only fetch media ids from your own inbound events
MEDIA_TOO_LARGE413Media exceeds the size limitDo not proxy files above the limit
MEDIA_UPSTREAM502Could not resolve/download the media from MetaRetry; the media may have expired
TEMPLATE_NOT_APPROVED422The template you tried to send is known and NOT APPROVED (details.status = its state)Only send approved templates; check status in the panel or wait for Meta
TEMPLATE_HEADER_MEDIA_REQUIRED422The template has an IMAGE/DOCUMENT/VIDEO header and the send carries no header component. Caught before Meta (which answers an opaque 132000). details.example is the exact component to addAdd the header component with the file — link (public https) or id
TEMPLATE_PARAM_INVALID_CHARS400A text parameter (body or header, type: text) contains a line break (\n), a carriage return (\r), a tab (\t) or 5+ consecutive spaces. Caught before Meta (which answers 132018). details = component, parameter ({{n}}), character — never the value. ⚠ Enabled per deployment (TEMPLATE_PARAM_GUARD_ENABLED); off, the send goes to Meta as beforeReplace line breaks with · or commas and collapse repeated spaces
TEMPLATE_HEADER_MEDIA_NOT_SUPPORTED422The send carries a media header parameter but the template has no media headerDrop the header component (a TEXT header takes text parameters, not a file)
TEMPLATE_HEADER_MEDIA_TYPE_MISMATCH422The header parameter type doesn't match the approved header format (details.expectedParameterType)Use the type the template declares — not the file's mime. A JPG on a DOCUMENT-header template still goes as document
TEMPLATE_PRECHECK_FAILED400The template would be rejected by Meta (details.issues[] lists each blocker + how to fix)Fix the issues and retry — the pre-checker caught them before Meta did
TEMPLATE_META_REJECTED400Meta rejected the template at creation (message = Meta's reason)Adjust per Meta's message and create again (an approved template can't be edited)
TEMPLATE_NOT_FOUND404No template with that id for this accountCheck the tpl_… id
TEMPLATE_NAME_TAKEN409A template with that name+language already exists on this numberUse a different name (Meta forbids duplicate names)
TEMPLATE_CATEGORY_INVALID400category must be UTILITY or MARKETING (draft approve/edit). AUTHENTICATION is not creatable — Meta wants a shape this builder doesn't produceSend UTILITY or MARKETING; for an auth template, create it in Meta Business Manager and sync it
TEMPLATE_RUBRO_INVALID400suggestedRubro is not a known catalog rubroOmit it or use a valid rubro
TEMPLATE_DRAFT_LIMIT_INVALID400draftLimit must be an integer between 1 and 100Send a value in range or omit it
TEMPLATE_DRAFT_NOT_FOUND404No pending draft with that id for this accountCheck the tpl_… id
REQUEST_BODY_TOO_LARGE413The request body is larger than the limit (1 MB; 5 MB on /webhook)Do not put a file inside the JSON. WAIA Connect stores no files: media travels by link and Meta downloads it. Host the file on a public https URL and send {"type":"document","document":{"link":"https://…"}}. ⚠ A Google Drive or Dropbox share URL returns an HTML page, not the file — Meta rejects it (MEDIA_DOWNLOAD_FAILED). If the body really is a large JSON, split the request
REQUEST_BODY_INVALID_JSON400The request body is not valid JSONCheck for a trailing comma, single quotes instead of double, or an empty body sent with Content-Type: application/json
REQUEST_BODY_UNSUPPORTED_ENCODING415The body uses an encoding or charset we cannot readSend UTF-8 JSON with Content-Type: application/json
INTERNAL500Internal server errorRetry; if it persists, contact support
APIKEY_NAME_REQUIRED400A non-empty name is required to create an API keySend a name
APIKEY_NOT_FOUND404No API key with that id for this accountCheck the key id
WEBHOOK_URL_REQUIRED400A url string is requiredSend a url
WEBHOOK_URL_UNSAFE400URL must be https to a public host (private/loopback/link-local rejected)Use a public https URL
WEBHOOK_EVENTS_INVALID400events must be known event typesUse the 20 subscribable types of DeliveryEventType (message.received … billing.amount_updated). webhook.test is not subscribable
WEBHOOK_NOT_FOUND404No webhook endpoint with that id for this accountCheck the wh_… id
WEBHOOK_STATIC_HEADER_INVALID400The static header name is invalid or reservedUse a valid header name; never Authorization/Cookie/Host/Content-*
WEBHOOK_CREATE_FAILED500Could not create the webhook endpointRetry
ALERT_NOT_FOUND404No alert with that id for this accountCheck the alert id
CONNECTION_QUOTA_EXCEEDED429This number's monthly message limit is exhaustedRaise the limit for THIS connection (≠ upgrading the plan)
CONNECTION_EXTERNAL_ID_TAKEN409Another connection in this account already uses that externalIdPick a different externalId (unique within an account)
CONNECTION_LIMIT_INVALID400monthlyMessageLimit must be a non-negative integer or nullFix the value
INVALID_DATE400from/to must be YYYY-MM-DDFix the date
INVALID_PERIOD400period must be YYYY-MMFix the period
WEBHOOK_CONNECTION_INVALID400connectionId is not a valid connection idSend a numeric connection id or omit for the account default
WEBHOOK_CONNECTION_NOT_FOUND404No connection with that id for this accountCheck the connection id
ONBOARDING_MODE_INVALID400mode must be cloud_api, coexistence, or omittedFix mode
ONBOARDING_ATTEMPT_STATUS_INVALID400Unsupported signup-attempt status (abandoned is written by the server only)Send one of popup_returned, preflight_ok, completed, cancelled, failed
ONBOARDING_LANG_INVALID400lang must be es, it, en, pt, or omittedFix lang
ONBOARDING_EXPIRY_INVALID400expiresIn/expiresAt must be a single value between 5 minutes and 30 daysSend one of them, in range
ONBOARDING_RETURN_ORIGIN_INVALID400returnOrigin must be an exact https origin (public, no path)Send https://host (SSRF-guarded)
ONBOARDING_REDIRECT_URL_INVALID400redirectUrl must be a public https URLSend an https URL (SSRF-guarded)
ONBOARDING_HISTORY_INVALID400historyDelivery must be true, false, or omittedSend a boolean, or omit it so the hosted page asks
HISTORY_LIMIT_INVALID400limit must be an integer between 1 and 5Fix limit (default 1)
HISTORY_CURSOR_INVALID400after is not a cursor this endpoint returnedSend the nextCursor of the previous page, or omit it to start over
HISTORY_BATCH_NOT_FOUND404No history batch with that id for this connectionCheck the hb_… id (it comes in data[].batchId)
HISTORY_BATCH_GONE410The batch is no longer available: it expired after 7 days, or it could never be storedNothing to confirm; history.completed tells you how many expired
BRAND_LOGO_URL_INVALID400brandLogoUrl must be a public https URLUse a public https image URL (SSRF-guarded)
BRAND_COLOR_INVALID400brandColor must be a #RRGGBB hex colorFix the color
BRAND_EMAIL_INVALID400brandSupportEmail must be a valid emailFix the email
BRAND_WEBSITE_INVALID400brandWebsite must be an https URLFix the URL