Espelho · Sincronização
Sincroniza o histórico de conversas e a lista de contatos do WhatsApp Business App (modo coexistência) para a Cloud API.
A sincronização é disparada manualmente depois que o cliente conecta o número via Embedded Signup — e precisa acontecer dentro de 24 horas.
Pré-requisitos
- O cliente autorizou o compartilhamento no celular. Durante o Embedded Signup, o WhatsApp Business App pede permissão para compartilhar histórico e contatos. Se ele recusou, nada será enviado.
- Os campos de webhook estão assinados. Ative
historyesmb_app_state_syncno endpoint de webhook do número.
Janela de 24 horas e disparo único
Você tem exatamente 24 horas a partir do Embedded Signup. Passou o prazo, não há como recuperar — o cliente precisa refazer o onboarding.
Cada tipo de sincronização (history e smb_app_state_sync) pode ser disparado
uma única vez por integração.
Como o histórico chega
Em múltiplos webhooks assíncronos, divididos em fases e blocos:
phase | Período nominal |
|---|---|
0 | dia 0 → dia 1 |
1 | dia 1 → dia 90 |
2 | dia 90 → dia 180 |
Na prática as fases se sobrepõem — mensagens de qualquer data podem aparecer
em qualquer fase. Não use a fase para inferir período; ordene tudo por
timestamp.
Cada fase pode vir em vários blocos (chunk_order), não necessariamente em
ordem. O campo progress (0–100) indica o avanço geral: progress: 100 na
última fase significa histórico completo.
Um único webhook pode carregar milhares de mensagens:
webhook (1 POST)
└── value.history[]
└── threads[] ← 1 thread = 1 conversa com 1 contato
└── messages[] ← mensagens daquela conversa
Duplicatas — regra obrigatória
O mesmo thread.id aparece em vários webhooks e a mesma mensagem pode vir
repetida. Ao processar:
- Junte todas as mensagens com o mesmo
thread.idde todos os webhooks. - Deduplique por
wamid(message.id). - Ordene por
timestamp(Unix em segundos, 10 dígitos).
Use history_context.from_me para saber a direção: true = enviada pela
empresa, false ou ausente = recebida.
Mídias no histórico
Mídias não vêm dentro das threads — aparecem como type: "media_placeholder",
sem conteúdo. O arquivo real chega em webhooks separados (value.messages ou
value.message_echoes), casados pelo wamid. Só mídias dos últimos ~14 dias
têm arquivo disponível.
Contatos
Chegam geralmente em um único webhook, no array state_sync. Contas grandes
podem gerar vários, sem ordenação garantida.
action: "add"→ adicionar ou atualizar contatoaction: "remove"→ remover contato- Timestamp em milissegundos (13 dígitos) — diferente do histórico, que usa segundos.
Depois da sincronização inicial, alterações futuras nos contatos continuam
chegando automaticamente por smb_app_state_sync, sem precisar chamar este
endpoint de novo.
Disparar sincronização
Dispara a sincronização do histórico de conversas ou da lista de contatos do