Response Format
The success and error envelopes, pagination, response headers, error codes and idempotency.
Success
A successful response wraps the result in data. It is an object or an array, depending on the route.
{
"data": {
"message_id": "true_5581999999999@c.us_3EB0C767D26A1D5E",
"chat_id": "5581999999999@c.us"
}
}Most routes answer 200. Creating a label or a group answers 201.
Lists and pagination
The list routes take limit and offset and return a plain array in data, with no total count.
| Route | limit | Default |
|---|---|---|
GET /chats | 1 to 100 | 20 |
GET /chats/{chatId}/messages | 1 to 100 | 20 |
GET /contacts | 1 to 500 | 100 |
For the next page, advance offset by limit. Stop when a page comes back empty. Messages also accept before and after (Unix seconds, exclusive) to filter by time.
Data passed through from WhatsApp
Some group routes (GET /groups, POST /groups, GET /groups/{gid}, GET /groups/{gid}/participants, and adding or removing participants) return the data as WhatsApp gives it, unchanged. Its fields may vary: read only what you need and don't fail on fields you don't know.
Errors
Every error has the same shape:
{
"error": {
"codigo": "numero_sem_whatsapp",
"mensagem": "Este numero nao tem conta no WhatsApp. Nada foi enviado."
}
}| Field | Meaning |
|---|---|
codigo | A stable error code. Decide what to do based on it. |
mensagem | A human-readable explanation, currently in Portuguese. Log it or show it, but don't parse it: it may change. |
The field names (codigo, mensagem) and the error codes are Portuguese identifiers. They are stable and safe to match in your code.
Common error codes
| Status | Code | What to do |
|---|---|---|
400 | dados_invalidos | A field in the body, query or path is wrong or missing. The message names the field. |
400 | requisicao_invalida | The body is not valid JSON. |
400 | destino_invalido | to is neither a phone number (country code + area code + number) nor a chat ID. |
400 | midia_invalida | Send url or base64, exactly one of them. A url must be public http(s); a base64 must be valid. |
400 | idempotency_key_invalida | Idempotency-Key must be 1 to 255 visible characters, without spaces. |
401 | chave_invalida | The API key is missing, malformed, unknown or revoked. |
402 | sem_assinatura | The account has no active subscription. Reactivate the plan in the dashboard. |
403 | sem_permissao | WhatsApp refused for lack of permission (for example, the number is not a group admin). Nothing was done. |
404 | rota_nao_encontrada | The route does not exist. |
400 / 404 / 409 / 422 | recusado_pelo_whatsapp | WhatsApp refused the request (invalid data, an item that doesn't exist, or a conflict with the current state). The status repeats WhatsApp's. |
409 | conexao_desconectada | The number is disconnected from WhatsApp. Reconnect it (scan the QR code) and try again. |
409 | instancia_suspensa | The connection is suspended for billing reasons. Nothing is sent. |
409 | sessao_em_estado_inesperado | The WhatsApp session is not in the right state for this. Check the connection and try again. |
409 | requisicao_em_andamento | A request with the same Idempotency-Key is still running. Wait for its answer. |
413 | corpo_grande_demais | The request body is larger than 25 MB. Send large files by url. |
413 | midia_grande | The file at url is larger than 50 MB. Nothing was sent. |
415 | tipo_de_conteudo_nao_suportado | Send the body as application/json. |
422 | numero_sem_whatsapp | The number has no WhatsApp account. Nothing was sent. Check numbers with GET /contacts/check. |
422 | idempotency_key_reutilizada | The same Idempotency-Key was used for a different request. Use one value per request. |
422 | midia_indisponivel | The url didn't deliver the file (name doesn't resolve, non-2xx answer, too many redirects, empty). |
422 | destino_nao_suportado | Status and broadcast lists (@broadcast) are not valid destinations. Use a chat or a group. |
429 | muitas_tentativas, excesso_de_pedidos, consulta_repetida | Abuse protection. Wait for Retry-After. See Rate limits. |
429 | bloqueio_temporario, limite_do_whatsapp | WhatsApp itself is limiting this number. Stop sending and wait. |
500 | erro_interno | Unexpected error on our side. Contact support with the x-request-id. |
501 | recurso_nao_suportado | This feature is not available for this WhatsApp connection. |
502 / 504 | resultado_incerto | WhatsApp didn't confirm in time and the message may have gone out. Check the chat, or wait for message.sent, before resending. |
502 / 503 | whatsapp_indisponivel | Temporary WhatsApp instability. Nothing was sent; try again shortly (the 503 carries Retry-After). |
503 | servidor_offline | The server that hosts this connection is down. Try again in a few minutes. |
503 | instancia_sem_servidor | The connection is not assigned to a WhatsApp server. Contact support. |
503 | banco_indisponivel | Momentary instability on our side. Try again after Retry-After. |
504 | whatsapp_sem_resposta | WhatsApp didn't answer a read in time. Try again shortly. |
Route-specific codes, such as formato_de_voz_invalido, lista_so_individual or etiquetas_indisponiveis, are explained in the guides and listed per route in the API Reference tab.
Treat resultado_incerto differently: the message may already be on the recipient's phone. Check the chat before resending, or retry with the same Idempotency-Key, which returns the same error instead of sending twice.
Response headers
| Header | When | Meaning |
|---|---|---|
x-request-id | Every response | The request id. Include it when you contact support, so we can find the request. |
idempotent-replayed | Repeated Idempotency-Key | true when the response is the stored one from an earlier request: nothing was done again. |
Age | Some reads | The response came from a short cache (up to 10 seconds) instead of WhatsApp. See Rate limits. |
Retry-After | 429 from abuse protection, some 503 | How many seconds to wait before trying again. |
Idempotency
Every route that changes something (POST, PUT, PATCH and DELETE) accepts the optional Idempotency-Key header. Repeating the same value, with the same API key, within 24 hours returns the first response with idempotent-replayed: true, without sending again.
- Use one value per message: a UUID, your order id or the id of the workflow run.
- Same value, different request (other body or other route):
422 idempotency_key_reutilizada. - First request still running:
409 requisicao_em_andamento. Wait for it. - Error where nothing went out (validation,
402,409,422...): the value is released, so you can fix the request and retry with the same value. resultado_incerto: the value stays taken, and a retry returns the same error instead of risking a duplicate message.
n8n, Make and many HTTP clients retry automatically when a response is slow. Without an Idempotency-Key, each retry can become another WhatsApp message.

