> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Melhores práticas da WhatsApp Messages API

> Crie fluxos de envio de mensagens do WhatsApp confiáveis, em conformidade e observáveis para produção.

Use estas práticas para enviar mensagens do WhatsApp com confiabilidade em escala de produção. Você escolherá o endpoint correto, correlacionará cada tentativa, convergirá o estado de entrega, fará novas tentativas com segurança, aplicará o consentimento e controlará a taxa de transferência.

## Antes de começar

* Conecte e registre os números de telefone comerciais do WhatsApp que enviarão mensagens.
* Armazene sua chave de API da YCloud no servidor.
* Configure um endpoint de webhook assinado para `whatsapp.message.updated`.
* Defina como seu sistema registra consentimento, cancelamentos de inscrição (opt-outs), finalidade da mensagem e retenção.
* Atribua responsáveis pelo envio, processamento de webhooks e resposta a incidentes.

## Escolha o endpoint de envio

Use o endpoint enfileirado por padrão. Use o envio direto apenas quando o aplicativo precisar saber se o WhatsApp aceitou o envio antes de continuar.

| Endpoint | Escolha-o quando | Efeito operacional |
| - | - | - |
| `POST /whatsapp/messages` | Você envia notificações, campanhas ou outro tráfego de saída normal. | A YCloud aceita a solicitação e a envia de forma assíncrona. Seu aplicativo pode absorver picos com sua própria fila. |
| `POST /whatsapp/messages/sendDirectly` | Você envia uma OTP ou outra mensagem com urgência de tempo que exige envio síncrono. | A solicitação aguarda o envio para a WhatsApp Business API. Ela não aguarda a entrega final. |

Uma resposta bem-sucedida de qualquer um dos endpoints não é prova de entrega. Armazene o `id` da mensagem retornado e use eventos de `whatsapp.message.updated` para saber se a mensagem foi `sent`, `failed`, `delivered` ou `read`.

<Warning>
  Não mude toda uma carga de trabalho de alto volume para `sendDirectly` para reduzir
  a latência de fila. Chamadas síncronas retêm recursos do aplicativo e ainda exigem
  tratamento de status assíncrono.
</Warning>

## Crie um registro de envio interno

Crie um registro durável antes de chamar a API. Forneça ao registro uma chave de negócios exclusiva, como o ID do evento do pedido mais a finalidade da mensagem. Imponha essa exclusividade em seu banco de dados para que workers concorrentes não possam enviar o mesmo evento de negócios duas vezes.

Registre pelo menos:

| Campo | Finalidade |
| - | - |
| Chave de negócios | Evitar que dois workers criem tentativas separadas para o mesmo evento de negócios. |
| `externalId` | Correlacionar dados da YCloud com seu registro interno e relatórios de reconciliação. |
| `id` da YCloud | Recuperar a mensagem e associar eventos de status. |
| `wamid` | Correlacionar com o WhatsApp após o envio quando esse valor estiver disponível. |
| Endpoint e tentativa | Explicar como a mensagem foi enviada e quantas tentativas de transporte ocorreram. |
| Status atual e carimbos de data/hora | Construir a visualização operacional atual mantendo o histórico de eventos. |

Use um `externalId` opaco que não contenha o conteúdo da mensagem nem dados pessoais. A API recomenda um valor exclusivo, mas `externalId` é um campo de referência. Ele não é uma chave de idempotência do lado do servidor e não torna seguras solicitações `POST` repetidas.

## Conecte a resposta a webhooks de status

O exemplo a seguir usa os mesmos identificadores em todo o fluxo de trabalho de envio.

### 1. Enviar a mensagem

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/messages \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "to": "+16315552222",
    "type": "template",
    "externalId": "order-ready-10001",
    "filterUnsubscribed": true,
    "filterBlocked": true,
    "template": {
      "name": "orders_pickup_ready_v2",
      "language": {
        "code": "en_US",
        "policy": "deterministic"
      }
    }
  }'
```

### 2. Armazenar a resposta aceita

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "MESSAGE_ID",
  "wabaId": "WHATSAPP_BUSINESS_ACCOUNT_ID",
  "from": "+16315551111",
  "to": "+16315552222",
  "type": "template",
  "status": "accepted",
  "externalId": "order-ready-10001",
  "createTime": "2026-08-27T09:00:00.000Z"
}
```

Grave `MESSAGE_ID`, `accepted` e o tempo de resposta no registro interno existente. Não marque a notificação de negócios como entregue.

### 3. Aplicar eventos de status posteriores

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "evt_MESSAGE_STATUS_1",
  "type": "whatsapp.message.updated",
  "apiVersion": "v2",
  "createTime": "2026-08-27T09:00:02.000Z",
  "whatsappMessage": {
    "id": "MESSAGE_ID",
    "wamid": "wamid.BgNODYxN...",
    "status": "sent",
    "externalId": "order-ready-10001",
    "sendTime": "2026-08-27T09:00:01.000Z"
  }
}
```

Faça a correspondência do evento por `whatsappMessage.id`. Use `externalId` para reconciliação de negócios e `wamid` para investigação no lado do provedor.

## Construa um modelo de status convergente

A progressão comum é `accepted` → `sent` → `delivered` → `read`. `failed` pode ocorrer antes ou depois de uma atualização de `sent`. Os webhooks podem ser duplicados, atrasados ou entregues fora de ordem. Uma atualização de `read` também pode chegar sem um evento `delivered` separado.

Processe cada evento da seguinte forma:

1. Verifique a assinatura do webhook em relação ao corpo bruto da solicitação (raw body).
2. Armazene o evento de forma durável, usando o `id` do evento como a chave de desduplicação.
3. Retorne uma resposta `2xx` imediatamente e, em seguida, processe o evento de forma assíncrona.
4. Faça a correspondência do `whatsappMessage.id` com o registro de envio interno.
5. Armazene o status do evento e os carimbos de data/hora disponíveis da mensagem. Mantenha os metadados brutos do evento necessários para auditoria, mas remova o conteúdo desnecessário da mensagem.
6. Atualize a visão de negócios atual sem descartar evidências conflitantes ou posteriores. Trate `read` como evidência de que a entrega ocorreu, mesmo quando o evento separado `delivered` estiver ausente.
7. Recupere `GET /whatsapp/messages/{id}` quando os eventos entrarem em conflito, um status terminal estiver ausente além do seu objetivo de serviço ou o pipeline de webhook estiver indisponível.

Não implemente o modelo de status como uma regra que só aceita um status de maior prioridade. As atualizações reais de entrega nem sempre chegam nessa ordem. Mantenha um histórico de eventos e garanta que a reconciliação consiga corrigir a visualização atual.

## Tentar novamente sem criar envios duplicados

Classifique a falha antes de tentar novamente.

| Falha | Ação recomendada |
| - | - |
| `400`, `404` ou `422` | Corrija a requisição, o recurso, o modelo ou a regra de negócio. Não tente novamente a requisição inalterada. |
| `401` ou `403` | Corrija a autenticação ou o acesso à conta. Não tente novamente com credenciais inalteradas. |
| `429` | Reduza a simultaneidade e tente novamente após um intervalo. |
| `5xx` | Tente novamente em caso de falha temporária com backoff exponencial, variação (jitter) e um número máximo de tentativas. |
| Tempo limite ou perda de conexão | Trate o resultado como ambíguo. Reconcilie antes de criar outro envio sempre que houver chance de a requisição ter chegado à YCloud. |

Uma política segura de aplicação pode começar com um número reduzido de tentativas, intervalos exponenciais, variação completa (full jitter) e um tempo total máximo decorrido. Esses são controles da aplicação, não garantias da API. Envie tentativas esgotadas para uma fila de análise em vez de tentar indefinidamente.

Antes de cada nova tentativa:

* Bloqueie ou reivindique atomicamente a chave de negócio interna.
* Verifique se o registro já possui um `id` da YCloud ou um evento de status.
* Não use um novo `externalId` para ocultar uma tentativa ambígua anterior.
* Interrompa após atingir o limite configurado de tentativas ou de tempo de espera.
* Exija uma ação deliberada do operador antes de reenviar um envio ambíguo.

## Escolher modelos e mensagens de sessão

Use um modelo aprovado ao iniciar uma mensagem de negócios ou enviar fora da janela de atendimento ao cliente de 24 horas. Selecione a categoria do modelo a partir do motivo do usuário para receber a mensagem e mantenha seu nome, idioma e contrato de variáveis na configuração da aplicação.

Use mensagens de texto, mídia, interativas, de localização, de contato ou de reação apenas quando a janela de atendimento ao cliente estiver aberta e esse tipo de conteúdo for permitido. Determine a janela a partir da mensagem mais recente do cliente. Não deduza uma janela aberta a partir da sua última mensagem enviada.

Consulte [Gerenciar modelos do WhatsApp](/pt/api-reference/guides/whatsapp-platform/manage-whatsapp-templates) para controle de versão de modelos, critérios de aprovação, localidades e reversão.

## Gerenciar mídia com eficiência

* Valide o tipo MIME suportado e o tamanho do arquivo antes de fazer o upload. Não tente novamente
  um arquivo muito grande ou não suportado sem alterações.
* Faça o upload com o número de telefone comercial que enviará a mensagem.
* Reutilize o ID de mídia retornado para envios repetidos do mesmo recurso aprovado
  enquanto ele permanecer válido. As mídias enviadas permanecem armazenadas por 30 dias.
* Armazene a soma de verificação (checksum) do recurso, o tipo MIME, o ID de mídia, o remetente e o horário de expiração para que
  os workers não façam o upload do mesmo arquivo para cada destinatário.
* Faça o upload novamente após a expiração ou quando o contexto do remetente mudar.
* Use uma URL pública quando o esquema da mensagem exigir um link, incluindo
  mídias em cabeçalhos de mensagens interativas.
* Faça o streaming de uploads grandes diretamente do armazenamento, defina tempos limite para requisições e exclua arquivos
  locais temporários após o uso.

## Garantir o consentimento e minimizar dados

Registre a origem do consentimento, a finalidade, o horário e o canal permitido antes de enviar. Aplique a opção de cancelamento (opt-out) válida mais recente em campanhas, fluxos transacionais onde a política exigir, novas tentativas e reenvios manuais.

Para `POST /whatsapp/messages`, defina `filterUnsubscribed: true` e `filterBlocked: true` quando o fluxo de trabalho precisar aplicar as listas de supressão da YCloud. O padrão desses campos é `false`. Eles não se aplicam a `sendDirectly`, portanto, um fluxo de envio direto deve verificar a supressão antes da chamada de API.

Os filtros de supressão são uma verificação final de segurança, não um substituto para o consentimento. Armazene apenas os identificadores e metadados de entrega necessários para a finalidade declarada. Exclua chaves de API, variáveis de modelo, corpos de mensagens e números de telefone dos logs gerais da aplicação. Aplique controles de retenção e de acesso aos registros de mensagens e Webhooks.

## Controlar o throughput de lotes

Coloque o trabalho em lote em uma fila limitada e envie por meio de um pool fixo de workers. Monitore a simultaneidade separadamente por conta e número de telefone comercial para que um único remetente ou tenant não consuma todos os workers.

Aplique contrapressão (backpressure) quando qualquer um destes sinais aumentar:

* respostas `429`
* latência e tempos limites de requisição
* respostas `5xx`
* tempo na fila ou acúmulo de tentativas
* atraso no Webhook e mensagens `accepted` não resolvidas

Reduza a simultaneidade quando a YCloud ou a entrega posterior ficarem lentas. Retome gradualmente após a normalização. Não tente reenviar mensagens com falha em uma taxa superior à do envio original.

Monitore pelo menos o volume de requisições, a taxa de aceitação, a taxa de erros por status HTTP e código de erro, a taxa de status de entrega, o tempo de `accepted` para cada status posterior, o tamanho da fila, a idade do item mais antigo na fila, a contagem de tentativas, o atraso no Webhook, a contagem de deduplicações e o desvio de reconciliação. Crie alertas para alterações contínuas em relação à sua linha de base normal, não para uma única mensagem que falhou.

## Antipadrões comuns

* Marcar uma mensagem como entregue quando a API retorna `accepted`.
* Tratar `externalId` como uma chave de idempotência da YCloud.
* Tentar novamente cada resposta que não seja `2xx` ou timeout sem limite de tentativas.
* Usar `sendDirectly` para todo o tráfego.
* Presumir que os webhooks são únicos, ordenados ou completos.
* Enviar mensagens de formato livre fora da janela de atendimento ao cliente.
* Fazer upload do mesmo arquivo de mídia para cada destinatário.
* Depender de filtros de supressão sem registrar o consentimento.
* Registrar em log chaves de API, payloads completos ou dados pessoais desnecessários.
* Iniciar um lote com concorrência ilimitada e sem backpressure.

## Checklist para entrada em produção

* [ ] A escolha do endpoint corresponde à carga de trabalho e ao requisito de latência.
* [ ] Uma regra de unicidade no banco de dados protege a chave de negócios interna.
* [ ] `externalId`, `id` da YCloud e `wamid` têm funções documentadas distintas.
* [ ] As respostas iniciais permanecem não finais até que a evidência de status chegue.
* [ ] Assinaturas de Webhook, desduplicação de eventos, confirmação rápida e repetição são testadas.
* [ ] Um job agendado de recuperação reconcilia eventos atrasados ou ausentes.
* [ ] Falhas que permitem nova tentativa e falhas que não permitem têm fluxos de tratamento limitados.
* [ ] As regras de modelo e janela de sessão são aplicadas antes do envio.
* [ ] Os uploads de mídia são validados, reutilizados, expirados e limpos com segurança.
* [ ] Os controles de consentimento, cancelamento de inscrição, lista de bloqueio, retenção e logs são verificados.
* [ ] As filas de lote têm limites de concorrência, backpressure, dashboards e alertas.
* [ ] Os operadores podem pausar envios e revisar tentativas ambíguas sem repeti-las automaticamente.

<CardGroup cols={2}>
  <Card title="Enviar uma mensagem do WhatsApp" icon="whatsapp" href="/pt/api-reference/guides/whatsapp-platform/send-whatsapp-message">
    Revise tipos de solicitação, campos, exemplos e dados de resposta.
  </Card>

  <Card title="Configurar webhooks" icon="webhook" href="/pt/api-reference/guides/api-fundamentals/configure-webhooks">
    Verifique assinaturas e processe entregas repetidas de eventos com segurança.
  </Card>

  <Card title="Fazer upload de mídia do WhatsApp" icon="upload" href="/pt/api-reference/guides/whatsapp-platform/upload-whatsapp-media">
    Faça upload de mídia compatível e reutilize o ID de mídia retornado.
  </Card>

  <Card title="Tratar erros da API" icon="triangle-exclamation" href="/pt/api-reference/guides/api-fundamentals/handle-errors">
    Analise respostas de erro e aplique novas tentativas limitadas.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.