Pular para o conteúdo
whatsapi.sh
Tema
Docs

Erros que dizem o que fazer

Todo erro é um envelope JSON com um código estável, uma mensagem que diz como resolver, e Retry-After em tudo que se resolve esperando. Esta página é a tabela que a sua lógica de retentativa precisa.

O formato

429 Too Many Requests
Retry-After: 42

{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Daily send limit reached (20/day on Free). It clears at midnight, or Starter sends 60/day",
    "messageKey": "serverErrors.dailyCapReached",
    "details": { "scope": "day", "limit": 20, "resetAt": "2026-08-25T03:00:00.000Z", "retryAfterSecs": 42 }
  }
}

messageKey é estável, pra você traduzir do seu jeito. message é o texto em inglês, de reserva. As recusas que pedem upgrade dizem qual é o plano mais barato que resolve, porque erro sem saída não é mensagem de erro.

Todos os códigos

400 VALIDATION_ERRORAlgum campo veio errado. `details` lista caminhos e regras, nunca os seus valores.
401 UNAUTHORIZED / INVALID_TOKENA chave está faltando, errada ou revogada. Mande `Authorization: Bearer wa_…`.
402 PAYMENT_REQUIREDUm limite que só compra levanta, como mais números ou envio em lote. Esperar não resolve.
403 FORBIDDENA conta está suspensa.
404 NOT_FOUNDEsse recurso não existe, ou não é seu.
409 NUMBER_NOT_CONNECTEDO número não tem uma sessão do WhatsApp que permita enviar. Abra Números, confira o WhatsApp no celular e reconecte. Tentar o envio de novo agora não resolve.
409 CONFLICTA requisição precisa de uma ação ou já está nesse estado. Um número restrito pede `recoveryConfirmed: true`, só depois de você conferir que o WhatsApp funciona no celular. Uma requisição com a mesma `Idempotency-Key` pode ainda estar rodando: espere o `Retry-After` e repita com a mesma chave.
422 IDEMPOTENCY_KEY_REUSEDEssa `Idempotency-Key` já foi usada em outra requisição. Mande uma nova. Esperar não resolve.
429 RATE_LIMIT_EXCEEDEDRápido demais. `Retry-After` diz exatamente quanto esperar.
429 QUOTA_EXCEEDEDLimite diário, cota mensal, ou o limite de conversas novas de um número. `details.scope` diz qual: `day`, `month` ou `newConversations`. `resetAt` diz quando libera.
429 PAIRING_COOLDOWNPedidos demais de código de pareamento para este número. `Retry-After` diz quando você pode pedir outro. Isso não é um tempo fixo de restrição.
502 GATEWAY_ERRORO WhatsApp recusou lá em cima. Tentar de novo pode funcionar.
504 GATEWAY_TIMEOUTO WhatsApp não confirmou a tempo. Confira a conversa e, se vier `details.messageId`, acompanhe esse id no webhook `message.status` antes de enviar de novo. Uma nova tentativa com a mesma `Idempotency-Key` recebe a mesma resposta, sem um segundo envio.
503 SERVICE_UNAVAILABLEUma dependência caiu. Tente de novo em instantes.

Quando o número cai

O celular pode perder a conexão, e uma conta nova pode ainda não ter número. Novos envios respondem 409 NUMBER_NOT_CONNECTED sem cobrar nada. As mensagens já na fila que ainda não saíram pausam até o número reconectar. Elas não viram falhas só porque ele caiu, e voltam a sair com o intervalo configurado. message.failed indica um envio que não pode continuar ou cujo resultado não é conhecido, não uma fila pausada.

  • Tenha um segundo canal. O que alguém precisa receber vai também por e-mail, ou por e-mail quando o WhatsApp recusar.
  • Antes de oferecer algo que só funciona pelo WhatsApp, como um código de login, confira se tem número conectado. Guarde a resposta por um minuto e jogue fora quando um envio voltar NUMBER_NOT_CONNECTED.
  • Sem número conectado, esconda essa opção e mostre o caminho pelo e-mail. Não mostre um botão que só pode falhar.
  • Se você tem webhook, o number.disconnected chega quando o número continua fora depois de 15 minutos de tentativas, e o number.connected quando ele volta.
GET /v1/numbers
import { Whatsapi } from "@whatsapi.sh/sdk";

const wa = new Whatsapi({ apiKey: process.env.WHATSAPI_KEY! });

const numbers = await wa.listNumbers();
const whatsappReady = numbers.some((n) => n.status === "connected");

Regras para tentar de novo

Respeite Retry-After num 429. Nunca repita um 402 automaticamente, porque ele se resolve com compra, não com espera. Num 504, não reenvie no escuro: o id da mensagem em details vai aparecer no seu webhook message.status se ela chegou, e reenviar sem conferir é como uma pessoa recebe mensagem duas vezes. Para repetir um envio sem risco, mande com o header Idempotency-Key e repita com o mesmo valor: você recebe a primeira resposta em vez de uma segunda mensagem. Os limites de taxa são proteção, não burocracia, e como não ser banido explica como ficar embaixo deles desde o começo.