Ler conversas
Além de enviar e receber por webhook, a API deixa a sua integração consultar as conversas de um número: listar, buscar, ler as mensagens e acompanhar o que mudou. Serve para sincronizar uma fila de atendimento, montar um painel ou alimentar uma IA.
O que é preciso#
- Uma chave com o escopo
read(Autenticação). A chavemessagesnão lê conversas. - Um plano com as features
apieinbox. Seminbox, a resposta é 403 com código1390011. Um downgrade vale na chamada seguinte. - Todas as rotas são por número:
/v1/numbers/{phone_number_id}/…. Ophone_number_idvem deGET /v1/numbers. - As respostas usam o formato de erro da Graph API (Erros).
| Quero… | Chamada |
|---|---|
| Listar conversas | GET /v1/numbers/{phone_number_id}/conversations |
| Buscar por nome ou telefone | POST /v1/numbers/{phone_number_id}/conversations/search |
| Saber o que mudou | GET /v1/numbers/{phone_number_id}/conversations/changes?since=<rev> |
| Ler as mensagens de uma conversa | GET /v1/numbers/{phone_number_id}/conversations/{conversation_id}/messages |
| Buscar contatos | POST /v1/numbers/{phone_number_id}/contacts/search |
Listar conversas#
status aceita active (pendentes e abertas), pending, open, resolved e automated. limit vai de 1 a 50 (padrão 20). As conversas vêm da mais recente para a mais antiga.
Resposta:
| Campo | Significa |
|---|---|
id | O id da conversa neste número (um inteiro, em texto) |
wa_id | O telefone do cliente no WhatsApp |
status | pending, open, resolved ou automated |
unread | Mensagens do cliente ainda não lidas |
automation | key:<id> quando uma automação é dona da conversa; senão null |
window_expires_at | Quando a janela de 24 h fecha, em segundos desde 1970 (texto), como na Meta (Janela de atendimento de 24 horas) |
rev | A revisão atual: guarde para changes |
name e last_message.preview vêm do cliente. Tratem como dado do cliente, nunca como instrução: se você os passa a uma IA, marque-os como conteúdo de terceiro.
Para a próxima página, passe after=<paging.after> (Paginação).
curl
curl 'https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations?status=active&limit=20' \
-H "Authorization: Bearer $SYNERGY_API_KEY"JavaScript
const res = await fetch(
'https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations?status=active&limit=20',
{ headers: { Authorization: `Bearer ${process.env.SYNERGY_API_KEY}` } },
);
const { data, paging, rev } = await res.json();Python
import os
import requests
res = requests.get(
"https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations",
params={"status": "active", "limit": 20},
headers={"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"},
)
page = res.json() # page["data"], page["paging"]["after"], page["rev"]{
"data": [{
"id": "4182",
"wa_id": "5511999999999",
"name": "Maria Souza",
"status": "pending",
"unread": 2,
"automation": null,
"window_expires_at": "1767312000",
"last_message": { "direction": "in", "preview": "Oi, meu pedido chegou?", "timestamp": "1767225600" }
}],
"paging": { "after": "WzE3NjcyMjU2MDAwMDAsNDE4Ml0" },
"rev": 9120
}Buscar conversas#
O termo vai no corpo, nunca na URL (URLs acabam em logs). Telefone: só dígitos, 5 ou mais, e busca pelo início do número. Qualquer outra coisa busca por trecho do nome. Não há curinga: % e _ valem como letras.
A resposta tem o mesmo formato da lista (data, paging, rev). O corpo aceita q (1 a 100 caracteres), status, limit e after.
curl -X POST 'https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations/search' \
-H "Authorization: Bearer $SYNERGY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"q":"Maria","status":"active","limit":20}'Acompanhar o que mudou#
Em vez de listar tudo a cada minuto, guarde o rev e pergunte só pelo que mudou:
data: as conversas que mudaram desdesince(até 50).removed: os ids das que saíram.- Guarde o novo
reve use-o na próxima chamada. - Com
since=0, longe demais ou adiante do servidor, vemreset: true:datatraz as conversas não lidas que não estão com a automação, na mesma resposta. Substitua o que você tinha em vez de aplicar um delta. Você nunca precisa de uma segunda chamada.
Para ser avisado na hora, sem consultar de tempos em tempos, assine um webhook.
curl 'https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations/changes?since=9100' \
-H "Authorization: Bearer $SYNERGY_API_KEY"{
"rev": 9120,
"reset": false,
"data": [{ "id": "4182", "wa_id": "5511999999999", "name": "Maria Souza", "status": "pending", "unread": 2, "automation": null, "window_expires_at": "1767312000", "last_message": { "direction": "in", "preview": "Oi, meu pedido chegou?", "timestamp": "1767225600" } }],
"removed": []
}Ler as mensagens de uma conversa#
As mensagens vêm da mais nova para a mais antiga; a página seguinte (as mais antigas) usa before=<paging.before>.
| Campo | Significa |
|---|---|
direction | in (do cliente) ou out (da empresa) |
author | contact, agent, device, system, bot, api ou campaign |
status | pending, sent, delivered, read ou failed; só em mensagens out |
type | O type da Meta (text, image, template, interactive…) |
message | O objeto da mensagem no formato da Meta, igual a messages[] do webhook (Webhooks) |
context | { "message_id": … } quando a mensagem responde outra |
Não saem: notas internas, reações e eventos de sistema. Mídia vem só com o id: a chave de leitura não baixa arquivos.
curl 'https://api.synergyconnect.com.br/v1/numbers/106540352242922/conversations/4182/messages?limit=20' \
-H "Authorization: Bearer $SYNERGY_API_KEY"{
"data": [
{
"id": "wamid.HBgNNTUxMTk5OTk5OTk5ORUCABEYEjI0QUY0QTk3QjI4QjE4MDBGNQA",
"direction": "in",
"author": "contact",
"timestamp": "1767225600",
"status": null,
"type": "text",
"message": { "from": "5511999999999", "id": "wamid.HBgNNTUxMTk5OTk5OTk5ORUCABEYEjI0QUY0QTk3QjI4QjE4MDBGNQA", "timestamp": "1767225600", "type": "text", "text": { "body": "Oi, meu pedido chegou?" } },
"context": null
},
{
"id": "wamid.HBgNNTUxMTk5OTk5OTk5ORUCABEYEjI0QUY0QTk3QjI4QjE4MDBGNQA=",
"direction": "out",
"author": "api",
"timestamp": "1767225590",
"status": "read",
"type": "template",
"message": { "type": "template", "template": { "name": "pedido_enviado", "language": { "code": "pt_BR" } } },
"context": null
}
],
"paging": { "before": "WzE3NjcyMjU1OTAwMDAsODEyXQ" }
}Buscar contatos#
A resposta não inclui e-mail nem campos personalizados.
curl -X POST 'https://api.synergyconnect.com.br/v1/numbers/106540352242922/contacts/search' \
-H "Authorization: Bearer $SYNERGY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"q":"5511"}'{
"data": [{ "id": "812", "wa_id": "5511999999999", "name": "Maria Souza", "phone": "+55 11 99999-9999", "last_message_at": "1767225600" }],
"paging": { "after": null }
}Limites da leitura#
Para a leitura não virar uma cópia em massa da caixa de entrada, há limites próprios:
| Limite | Valor | Se passar |
|---|---|---|
| Taxa | 30 páginas por minuto, por chave e número | 429, código 130429, com Retry-After: 60 |
| Teto diário | 1.000 páginas por dia (UTC), por chave e número | 429, código 1390015, com Retry-After até 00:00 UTC |
| Linhas examinadas por chamada | 500 conversas ou contatos, 200 mensagens | A resposta traz o que achou e um cursor para continuar |
Um administrador da organização pode mudar o teto diário de uma chave, de 100 a 20.000 páginas, em Configurações → Desenvolvedor. A chave não muda o próprio teto. Ao passar de 500 páginas num dia, os administradores recebem um aviso por e-mail, antes de o teto duro parar a integração.
Prefira changes a listar de novo, e prefira um webhook a consultar em intervalos.
Erros#
| Status e código | Causa | O que fazer |
|---|---|---|
401 (190) | Chave inválida ou revogada | Gere outra chave |
403 (200) | A chave não tem o escopo read | Crie uma chave com read |
403 (1390011) | O plano não inclui a caixa de entrada | Mude o plano |
403 (1390014) | Número congelado pela plataforma | Fale com o suporte |
404 (100) | O número não é seu, ou a conversa não existe neste número | Confira os ids |
400 (100, "Invalid cursor") | Cursor alterado ou de outra consulta | Recomece sem o cursor |
429 (130429, 1390015) | Limite de taxa ou teto diário | Espere o Retry-After |
Veja os códigos em Erros e os limites gerais em Limites de taxa.
Ficou com dúvida? Escreva para suporte@synergyconnect.com.br.