# Erros e idempotência Leia o status HTTP e o campo `error` juntos. Uma falha de transporte não significa necessariamente que uma mensagem deixou de ser enviada. ## Decida pelo resultado | HTTP / erro | Como tratar | |---|---| | `400` | Corrigir JSON, parâmetros, opções ou allowlist antes de repetir | | `401 unauthorized` | Conferir o tipo de header e o token do servidor ou da instância | | `403` em grupos | Conferir participação e permissões da conta | | `404` | Recurso inexistente; não presumir desconexão | | `405` | Corrigir o método; consultar o header `Allow` | | `409 whatsapp_disconnected` | Aguardar o fluxo autorizado de reconexão | | `409 session_owned_elsewhere` | Sessão pertence a outro worker; não duplicar a instância | | `409 media_reupload_pending` | Aguardar o reenvio da mídia e tentar o download depois | | `409 idempotency_in_progress` | Aguardar e repetir a mesma requisição com a mesma chave | | `422 idempotency_mismatch` | A chave foi reutilizada com método, caminho ou corpo diferentes | | `422 send_failed` / `number_not_on_whatsapp` | Falha definitiva desse envio; inspecionar o erro | | `429` | Respeitar `Retry-After` | | `500 whatsapp_reachout_timelock` | Bloqueio 463 do WhatsApp; observar `error_key` e `details.reachout_timelock.until` | | `501 calls_not_supported` | Verificar módulo habilitado e uso de instância `calls`; uma instância de mensagens mantém esse erro | | `502 storage_unavailable` | Aguardar recuperação do banco; respeitar `Retry-After` | | `503` em readiness | Banco não pronto | | `504 send_ambiguous` / `action_ambiguous` | Reconciliar pelo ID e pelos eventos antes de reenviar | ## Resultado ambíguo Um `504` pode ocorrer depois de o WhatsApp aceitar a operação. Guarde o identificador devolvido e consulte o status ou os eventos. Repetir com uma chave nova pode duplicar o efeito. Os aliases `messageid`, `messageId` e `id` dos envios se referem ao ID da mensagem do WhatsApp. Na edição, `editId` identifica a ação de edição e o ID original permanece separado. ## Rotas com idempotência | Operações | Retenção | |---|---| | `POST /instance/init` | 15 minutos | | `/send/*`, ações em mensagens e mutações de grupo indicadas no contrato | 24 horas | A página de cada endpoint informa se ele oferece `Idempotency-Key`. Não há garantia geral para qualquer POST. ```http Idempotency-Key: operacao-exemplo-001 ``` Crie uma chave por operação de negócio. Em uma repetição, mantenha a mesma chave, o método, o caminho e **os mesmos bytes do corpo**. Alterar espaços ou a ordem das chaves no JSON altera o hash. ## Replay de requisição `Idempotency-Replayed: true` indica uma resposta guardada. Respostas transitórias `409`, `429` e `5xx`, exceto `504`, liberam a chave. Resultados concluídos e ambíguos `504` permanecem guardados durante a retenção. Repetir um `504` e receber a mesma resposta não autoriza criar outra chave para o mesmo envio. ## Limites e correlação Use `X-Request-Id` para correlacionar falhas sem registrar tokens ou conversas. O corpo geral aceita 64 KiB; `/send/media` aceita 48 MiB de JSON e `/group/updateImage` 12 MiB. Bytes UTF-8 e caracteres não são a mesma medida. O orçamento do handler de envio é de 44 segundos. Configure o timeout do cliente de forma compatível e implemente a reconciliação de resultados ambíguos. ## Reentrega de eventos Idempotência de requisição e deduplicação de webhook são responsabilidades distintas. Para eventos, deduplique por servidor, instância e `X-AtendroZAP-Event-Id`. [POST /v1/events/{id}/replay](https://wpp.atendro.cloud/docs/api/replay-event.md) pode repetir um efeito já processado.