O envelope
Todo evento tem o mesmo formato externo. Sódata muda de um tipo para outro.
Todos os tipos de evento
Os eventos de contato carregam o contato inteiro, então a maioria das integrações nunca precisa chamar a API de volta. Os eventos de conversa e de mensagem carregam apenas ids: leia a conversa ou as mensagens dela pela API quando precisar do conteúdo.
Novos tipos de evento são adicionados com o tempo. Um endpoint inscrito em todos os eventos começa a recebê-los automaticamente. Responda
200 a qualquer type que você não trata.O objeto contato
Os eventos de contato incluem um objetocontact com os mesmos campos de GET /v1/contacts/{id}:
propertiesguarda suas propriedades personalizadas, indexadas pela chave da propriedade. Leiakindpara saber qual campovalue_*guarda o valor.- As propriedades de arquivo ficam de fora. O link de download de um arquivo é temporário e expiraria antes de uma nova tentativa de entrega chegar. Leia o contato pela API para obter um link novo.
- O contato é uma foto tirada quando a Ciarem prepara o evento, um instante depois da mudança. Se o contato mudou duas vezes em sequência rápida, os dois eventos podem mostrar o estado mais recente. Uma nova tentativa envia a mesma foto de novo, não uma nova.
Eventos de contato
contact.created
Um contato foi adicionado: por um colega, por uma importação, pela API, por uma integração como o HubSpot, ou porque uma pessoa nova escreveu por um canal.contact.updated
Os campos próprios de um contato (nome, email, telefone, cidade e assim por diante) ou uma das suas propriedades personalizadas mudaram.changed_fields lista o que mudou:
- Um campo simples aparece pelo nome:
"first_name","email". - Uma propriedade personalizada aparece como
properties.<key>:"properties.custom_budget". Cada propriedade personalizada que muda envia seu próprio eventocontact.updated.
contact.updated, contact.funnel_stage.changed e contact.owner.changed.
contact.deleted
Um contato foi excluído. O contato não existe mais, então só o id dele é enviado.contact.merged
Dois contatos foram mesclados.contact é o que permanece, com o resultado da mesclagem. merged_contact_id é o contato que foi incorporado a ele e não existe mais por conta própria: atualize os registros do seu lado que ainda apontam para ele.
contact.funnel_stage.changed
Um contato passou para outra etapa do funil, seja porque um colega o moveu ou porque o agente de IA o moveu. A nova etapa écontact.funnel_stage_id; a que ele deixou é previous_funnel_stage_id. Converta os ids de etapa em nomes com GET /v1/funnel-stages.
contact.owner.changed
O proprietário de um contato mudou. O novo proprietário écontact.owner_id; o anterior é previous_owner_id. Qualquer um dos dois pode ser null, o que significa que o contato não tem, ou não tinha, proprietário.
Eventos de conversa e de mensagem
Estes quatro eventos compartilham o mesmodata base:
conversation.created
Uma nova conversa começou.A Ciarem espera alguns segundos até o contato ser vinculado antes de enviar este evento, então
contact_id está presente quase sempre. No caso raro em que ele ainda é null, leia a conversa pela API um pouco depois. Essa espera curta também significa que o primeiro messages.inbound de uma conversa pode chegar antes do conversation.created dela.conversation.assigned
Uma conversa foi atribuída, por um colega que a assumiu, por um administrador, pelas suas regras de atribuição automática ou pelo agente de IA ao transferi-la.assignee_id é o colega e sempre vem preenchido. team_id é a equipe da conversa e pode ser null.
conversation.closed
Uma conversa foi resolvida, seja por um colega que terminou o atendimento ou pelo agente de IA que a encerrou. O corpo é odata base acima.
messages.inbound
Um cliente enviou uma mensagem. O evento diz qual conversa tem algo novo; ele não contém a mensagem em si.Eventos de formulários do WhatsApp
whatsapp_flow.completed
Um cliente enviou um formulário do WhatsApp. Dispara uma vez por envio, depois que a Ciarem salvou as respostas.answersusa os nomes internos dos campos do formulário, não o texto da pergunta. Para ler os valores por propriedade, useoutcome.saved(os campos e propriedades do contato onde as respostas foram gravadas) e leia o contato.outcome.errorslista as respostas que não puderam ser salvas, por exemplo um email que pertence a outro contato.- Um formulário de agendamento também traz
booking_id,start_at,end_at,meeting_urleattendee_emailemoutcome. - A resposta de uma pergunta de fotos ou documentos é uma lista de
{"file_name", "mime_type"}, eoutcome.filesdá seu estado:{"q3": {"status": "pending"}}. O evento é enviado antes de os arquivos serem salvos. Quando a pergunta salva em uma propriedade de arquivo, os arquivos salvos chegam com o eventocontact.updatedque vem a seguir. conversation_idpode sernullquando o formulário foi enviado com um modelo fora de uma conversa.
O evento de teste
Um teste enviado pelo painel ou comPOST /v1/webhook-endpoints/{id}/test parece um evento real, com duas diferenças:
- O
iddele começa comevt_test_, então você consegue distingui-lo e pular qualquer efeito real. - Se você não escolher um tipo de evento, o
typedele éteste odataé vazio:
GET /v1/webhook-event-samples retorna o corpo de exemplo de cada tipo, o que é útil para escrever testes do seu próprio handler.
Compatibilidade
Os corpos dos webhooks seguem a mesma regra do restante da API: as mudanças são aditivas. Novos tipos de evento, novos campos dentro dedata e novos valores em campos de texto podem aparecer a qualquer momento. Leia os campos de que você precisa, ignore o resto e confira o changelog quando algo parecer diferente.