Espelho · Sincronização
Syncs the conversation history and the contact list from the WhatsApp Business App (coexistence mode) into the Cloud API.
The sync is triggered manually after the customer connects the number through Embedded Signup — and it has to happen within 24 hours.
Prerequisites
- The customer approved sharing on their phone. During Embedded Signup, the WhatsApp Business App asks permission to share history and contacts. If they declined, nothing will be sent.
- The webhook fields are subscribed. Enable
historyandsmb_app_state_syncon the number's webhook endpoint.
24-hour window, one shot
You have exactly 24 hours from Embedded Signup. Miss it and there is no recovery — the customer has to redo onboarding.
Each sync type (history and smb_app_state_sync) can be triggered once per
integration.
How history arrives
Through multiple asynchronous webhooks, split into phases and chunks:
phase | Nominal period |
|---|---|
0 | day 0 → day 1 |
1 | day 1 → day 90 |
2 | day 90 → day 180 |
In practice the phases overlap — messages from any date can show up in any
phase. Don't use the phase to infer a period; sort everything by timestamp.
Each phase can arrive in several chunks (chunk_order), not necessarily in order.
The progress field (0–100) tracks the overall advance: progress: 100 on the
last phase means the history is complete.
A single webhook can carry thousands of messages:
webhook (1 POST)
└── value.history[]
└── threads[] ← 1 thread = 1 conversation with 1 contact
└── messages[] ← messages in that conversation
Duplicates — a hard requirement
The same thread.id shows up across several webhooks, and the same message can
arrive more than once. When processing:
- Collect every message with the same
thread.idfrom all webhooks. - Deduplicate by
wamid(message.id). - Sort by
timestamp(Unix seconds, 10 digits).
Use history_context.from_me for direction: true means the business sent it,
false or absent means it was received.
Media inside history
Media does not travel inside the threads — it shows up as
type: "media_placeholder", with no content. The real file arrives in separate
webhooks (value.messages or value.message_echoes), matched by wamid. Only
media from roughly the last 14 days still has a file available.
Contacts
Usually a single webhook, with every contact in the state_sync array. Large
accounts may produce several, with no guaranteed ordering.
action: "add"→ add or update a contactaction: "remove"→ remove a contact- Timestamps are in milliseconds (13 digits) — unlike history, which uses seconds.
After the initial sync, later contact changes keep arriving automatically through
smb_app_state_sync, with no need to call this endpoint again.
Trigger sync
Triggers the sync of conversation history or the contact list from the WhatsApp