Avisos (webhooks)
O DoneTalk avisa o seu sistema do que acontece, com um POST assinado para um endereço seu: uma campanha começou ou terminou, uma mensagem foi entregue ou lida, um contato respondeu, um atendimento foi concluído com o desfecho.
Cadastrar um endereço
Em Configurações › Integrações › Webhooks de saída, ou pela API com o escopo webhooks:manage:
curl -X POST https://api.donetalk.com/v1/c/{empresa}/webhooks \
-H "Authorization: Bearer $DONETALK_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://seu-sistema.com/donetalk/avisos", "events": ["campaign.completed", "campaign.recipient.replied", "conversation.closed"]}'A resposta traz o secret uma única vez: guarde para conferir as assinaturas.
O que chega
POST /donetalk/avisos HTTP/1.1
Content-Type: application/json
User-Agent: DoneTalk-Webhooks/1.0
DoneTalk-Signature: t=1792756800,v1=5f0c…
X-DoneTalk-Event: conversation.closed
X-DoneTalk-Delivery: 01a3e4f5-a6b7-7c8d-9e0f-1a2b3c4d5e6f{
"id": "01a3e4f5-…",
"type": "conversation.closed",
"occurredAt": "2026-10-24T12:20:41.000Z",
"customerId": "01a0c0de-…",
"data": { "...": "o conteúdo do evento" }
}Avisos de uma chave de teste trazem "test": true.
Conferir a assinatura
DoneTalk-Signature traz t (o horário do envio, em segundos) e v1, o HMAC SHA-256 de "<t>.<corpo exato>" com o seu secret. Recuse avisos com t de mais de 5 minutos atrás: assim ninguém reenvia um aviso antigo.
import crypto from "node:crypto";
function avisoValido(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const esperado = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(v1));
}import hmac, hashlib, time
def aviso_valido(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
esperado = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, parts["v1"])O cabeçalho antigo x-donetalk-signature (sha256= + HMAC do corpo, sem horário) segue junto até 21/01/2027.
Responder e tentativas
Responda 2xx em até 10 segundos; faça o trabalho pesado depois. Sem 2xx, o DoneTalk tenta de novo em 1 min, 5 min, 30 min, 2 h e 12 h. Depois de 20 falhas seguidas o endereço aparece como “Com falhas” (continua recebendo). Um mesmo aviso pode chegar mais de uma vez: use o id para não processar duas vezes. A ordem de chegada não é garantida: use occurredAt.
Eventos
| Evento | Quando chega |
|---|---|
conversation.opened | Um atendimento começou (o contato escreveu ou clicou num anúncio). |
conversation.closed | Um atendimento foi concluído, com o desfecho, quem concluiu (pessoa, assistente de IA ou regra automática), a anotação de encerramento, o contato, a equipe, as etiquetas, quanto durou e a campanha de origem. |
conversation.assigned | Um atendimento foi atribuído a uma pessoa. |
conversation.transferred | Um atendimento passou para outra equipe ou pessoa. |
conversation.reopened | Um atendimento concluído foi reaberto. |
contact.updated | Os dados de um contato mudaram. |
contact.consent_changed | O contato aceitou ou recusou receber mensagens de uma finalidade (marketing, por exemplo). |
message.received | O contato mandou uma mensagem. |
message.sent | Uma mensagem nossa saiu para o WhatsApp. |
message.delivered | Uma mensagem chegou ao celular do contato. |
message.read | O contato leu uma mensagem. |
message.failed | Uma mensagem não pôde ser entregue; error.code é o código da Meta. |
flow.event | Um fluxo chegou a um bloco “Registrar evento”, com o nome e os dados que o bloco define. |
appointment.booked | Um agendamento foi marcado. |
appointment.rescheduled | Um agendamento mudou de horário. |
appointment.cancelled | Um agendamento foi cancelado. |
appointment.confirmed | O contato confirmou o agendamento. |
appointment.attended | O contato compareceu. |
appointment.no_show | O contato faltou. |
campaign.started | A campanha começou a enviar; a lista foi fechada. |
campaign.paused | A campanha pausou: por uma pessoa, pela API ou por uma regra (modelo pausado, qualidade baixa, muitos pedidos para sair, orçamento). |
campaign.resumed | A campanha voltou a enviar. |
campaign.completed | A campanha terminou de enviar, com os totais. |
campaign.cancelled | A campanha foi cancelada. |
campaign.recipient.sent | A mensagem da campanha saiu para um contato. |
campaign.recipient.delivered | A mensagem da campanha chegou ao contato. |
campaign.recipient.read | O contato leu a mensagem da campanha. |
campaign.recipient.replied | O contato respondeu à campanha (a primeira resposta), por texto ou tocando num botão. |
campaign.recipient.failed | A mensagem da campanha falhou para um contato; errorCode é o código da Meta. |
campaign.recipient.opted_out | O contato pediu para não receber mais campanhas (botão “Parar promoções” ou recusa na Meta). |
Exemplos de cada evento
conversation.opened
Um atendimento começou (o contato escreveu ou clicou num anúncio).
{
"id": "01a3e4f5-…",
"type": "conversation.opened",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"handler": "flow",
"source": "inbound"
}
}conversation.closed
Um atendimento foi concluído, com o desfecho, quem concluiu (pessoa, assistente de IA ou regra automática), a anotação de encerramento, o contato, a equipe, as etiquetas, quanto durou e a campanha de origem.
{
"id": "01a3e4f5-…",
"type": "conversation.closed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"teamId": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
"assigneeId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"outcome": "converted",
"isSuccess": true,
"closedBy": {
"kind": "member",
"id": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"name": "Tayomara Batista"
},
"actorKind": "member",
"openedAt": "2026-10-24T12:00:04.000Z",
"firstResponseAt": "2026-10-24T12:05:10.000Z",
"messagesIn": 6,
"messagesOut": 7,
"outcomeLabel": {
"pt-BR": "Venda",
"en": "Sale",
"es": "Venta"
},
"outcomeCategory": "success",
"note": "Fechou o plano anual com o cupom ANA10.",
"contact": {
"name": "Ana Souza",
"phone": "5548999990001"
},
"team": {
"id": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
"name": "Vendas"
},
"tags": [
{
"id": "01a12150-3610-7c00-b680-188c2b4c7313",
"name": {
"pt-BR": "VIP",
"en": "VIP",
"es": "VIP"
}
}
],
"durationSeconds": 1237,
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b"
}
}conversation.assigned
Um atendimento foi atribuído a uma pessoa.
{
"id": "01a3e4f5-…",
"type": "conversation.assigned",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"assigneeId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"teamId": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
"reason": "distribution",
"previousAssigneeId": null,
"actorKind": "system"
}
}conversation.transferred
Um atendimento passou para outra equipe ou pessoa.
{
"id": "01a3e4f5-…",
"type": "conversation.transferred",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"teamId": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
"assigneeId": null,
"previousTeamId": null,
"previousAssigneeId": null,
"previousHandler": "flow",
"actorKind": "flow",
"reason": "Gestor de conta: Tayomara Batista"
}
}conversation.reopened
Um atendimento concluído foi reaberto.
{
"id": "01a3e4f5-…",
"type": "conversation.reopened",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677"
}
}contact.updated
Os dados de um contato mudaram.
{
"id": "01a3e4f5-…",
"type": "contact.updated",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"changes": [
"fields",
"displayName"
]
}
}contact.consent_changed
O contato aceitou ou recusou receber mensagens de uma finalidade (marketing, por exemplo).
{
"id": "01a3e4f5-…",
"type": "contact.consent_changed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"channel": "whatsapp",
"purpose": "marketing",
"status": "opted_out",
"source": "keyword",
"occurredAt": "2026-10-24T12:06:00.000Z"
}
}message.received
O contato mandou uma mensagem.
{
"id": "01a3e4f5-…",
"type": "message.received",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"type": "text"
}
}message.sent
Uma mensagem nossa saiu para o WhatsApp.
{
"id": "01a3e4f5-…",
"type": "message.sent",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"providerMessageId": "wamid.HBgMNTU0ODk5OTk5MDAwMRUCABEYEjE="
}
}message.delivered
Uma mensagem chegou ao celular do contato.
{
"id": "01a3e4f5-…",
"type": "message.delivered",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "delivered",
"occurredAt": "2026-10-24T12:00:06.000Z"
}
}message.read
O contato leu uma mensagem.
{
"id": "01a3e4f5-…",
"type": "message.read",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "read",
"occurredAt": "2026-10-24T12:03:51.000Z"
}
}message.failed
Uma mensagem não pôde ser entregue; error.code é o código da Meta.
{
"id": "01a3e4f5-…",
"type": "message.failed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "failed",
"occurredAt": "2026-10-24T12:00:06.000Z",
"error": {
"code": "131026",
"detail": "Message undeliverable"
}
}
}flow.event
Um fluxo chegou a um bloco “Registrar evento”, com o nome e os dados que o bloco define.
{
"id": "01a3e4f5-…",
"type": "flow.event",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"name": "lead.qualified",
"data": {
"plano": "anual",
"origem": "site"
}
}
}appointment.booked
Um agendamento foi marcado.
{
"id": "01a3e4f5-…",
"type": "appointment.booked",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "booked",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": null,
"cancelledAt": null,
"cancelledByKind": null,
"cancelReason": null,
"rescheduleCount": 0,
"previousStartsAt": null,
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}appointment.rescheduled
Um agendamento mudou de horário.
{
"id": "01a3e4f5-…",
"type": "appointment.rescheduled",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "booked",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": null,
"cancelledAt": null,
"cancelledByKind": null,
"cancelReason": null,
"rescheduleCount": 1,
"previousStartsAt": "2026-10-27T12:00:00.000Z",
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}appointment.cancelled
Um agendamento foi cancelado.
{
"id": "01a3e4f5-…",
"type": "appointment.cancelled",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "cancelled",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": null,
"cancelledAt": "2026-10-26T18:00:00.000Z",
"cancelledByKind": "contact",
"cancelReason": null,
"rescheduleCount": 0,
"previousStartsAt": null,
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}appointment.confirmed
O contato confirmou o agendamento.
{
"id": "01a3e4f5-…",
"type": "appointment.confirmed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "confirmed",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": "2026-10-26T14:00:00.000Z",
"cancelledAt": null,
"cancelledByKind": null,
"cancelReason": null,
"rescheduleCount": 0,
"previousStartsAt": null,
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}appointment.attended
O contato compareceu.
{
"id": "01a3e4f5-…",
"type": "appointment.attended",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "attended",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": null,
"cancelledAt": null,
"cancelledByKind": null,
"cancelReason": null,
"rescheduleCount": 0,
"previousStartsAt": null,
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}appointment.no_show
O contato faltou.
{
"id": "01a3e4f5-…",
"type": "appointment.no_show",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"id": "01a2f00d-1234-7abc-8def-0123456789ab",
"agendaId": "01a1228c-c584-73f7-b7e7-bfaa0d02fed0",
"agendaName": "Visitas aos imóveis",
"typeId": "01a1228c-c58f-796a-b3aa-54a953711c71",
"typeName": "Visita ao imóvel",
"typeColor": "#1daa61",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"contactName": "Ana Souza",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"channelId": "01a0cccc-0000-7000-8000-000000000002",
"memberId": "01a0cac1-4a6f-7646-b5f8-c1d19090016a",
"memberName": "Tayomara Batista",
"holderIds": [
"01a0cac1-4a6f-7646-b5f8-c1d19090016a"
],
"status": "no_show",
"startsAt": "2026-10-27T13:00:00.000Z",
"endsAt": "2026-10-27T14:00:00.000Z",
"timezone": "America/Sao_Paulo",
"location": "Rua Bahia, 120 – Higienópolis, São Paulo",
"locationKind": "address",
"onlineUrl": null,
"answers": {
"imovel": "AP-2231"
},
"notes": null,
"source": "api",
"createdByKind": "api_key",
"createdById": null,
"confirmedAt": null,
"cancelledAt": null,
"cancelledByKind": null,
"cancelReason": null,
"rescheduleCount": 0,
"previousStartsAt": null,
"publicToken": "r3WqZ8",
"createdAt": "2026-10-23T13:02:11.000Z"
}
}campaign.started
A campanha começou a enviar; a lista foi fechada.
{
"id": "01a3e4f5-…",
"type": "campaign.started",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "running",
"audience": 1240,
"skipped": 24,
"startedAt": "2026-10-24T12:00:00.000Z"
}
}campaign.paused
A campanha pausou: por uma pessoa, pela API ou por uma regra (modelo pausado, qualidade baixa, muitos pedidos para sair, orçamento).
{
"id": "01a3e4f5-…",
"type": "campaign.paused",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "paused",
"reason": "optout_rate",
"by": "system"
}
}campaign.resumed
A campanha voltou a enviar.
{
"id": "01a3e4f5-…",
"type": "campaign.resumed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "running",
"by": "api_key"
}
}campaign.completed
A campanha terminou de enviar, com os totais.
{
"id": "01a3e4f5-…",
"type": "campaign.completed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "completed",
"totals": {
"audience": 1216,
"sent": 1216,
"delivered": 1198,
"read": 874,
"replied": 141,
"failed": 18,
"skipped": 24,
"optedOut": 6
}
}
}campaign.cancelled
A campanha foi cancelada.
{
"id": "01a3e4f5-…",
"type": "campaign.cancelled",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "cancelled",
"by": "member"
}
}campaign.recipient.sent
A mensagem da campanha saiu para um contato.
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.sent",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"phone": "5548999990001",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"at": "2026-10-24T12:00:04.000Z"
}
}campaign.recipient.delivered
A mensagem da campanha chegou ao contato.
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.delivered",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"phone": "5548999990001",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"at": "2026-10-24T12:00:06.000Z"
}
}campaign.recipient.read
O contato leu a mensagem da campanha.
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.read",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"phone": "5548999990001",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"at": "2026-10-24T12:03:51.000Z"
}
}campaign.recipient.replied
O contato respondeu à campanha (a primeira resposta), por texto ou tocando num botão.
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.replied",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"buttonIndex": 0,
"text": "Quero o cupom"
}
}campaign.recipient.failed
A mensagem da campanha falhou para um contato; errorCode é o código da Meta.
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.failed",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"phone": "5548999990001",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889",
"errorCode": "131026"
}
}campaign.recipient.opted_out
O contato pediu para não receber mais campanhas (botão “Parar promoções” ou recusa na Meta).
{
"id": "01a3e4f5-…",
"type": "campaign.recipient.opted_out",
"occurredAt": "2026-10-24T12:04:02.000Z",
"customerId": "01a0c0de-…",
"data": {
"campaignId": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
"conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
"via": "button"
}
}