Neste artigo

Webhooks de saída: guia completo

Referência dos webhooks de saída do Codewo: os 11 eventos e o que cada um traz, cabeçalhos, validação da assinatura HMAC-SHA256, novas tentativas, pausa automática, rotação do segredo, log de entregas e o que ainda falta nos payloads.

Atualizado em 08 de outubro de 2026

Este guia detalha o que o Codewo envia ao seu sistema em cada evento, como validar a assinatura, o que acontece quando o seu servidor falha e como acompanhar tudo pela tela. Para a primeira configuração, comece por Começando com Webhooks.

O que é

Um webhook de saída é um POST em JSON que o Codewo faz para uma URL https:// sua quando um evento acontece. Cada endpoint escolhe os eventos que quer receber e tem o próprio segredo de assinatura (começa com whsec_).

A tela fica em Configurações → Integrações → Webhooks e depende do plano da empresa. Ver pede a permissão Ver integrações; criar, editar, testar, reenviar, pausar e excluir pedem Gerenciar integrações.

Os 11 eventos

Evento Nome na tela Quando dispara
conversation.created Conversa criada Conversa nova, em qualquer canal
conversation.assigned Conversa atribuída Muda o responsável (pessoa, equipe ou atendente virtual), inclusive quando fica sem ninguém
conversation.status_changed Status da conversa alterado Muda o status sem ser resolução: aberta, pendente, em andamento, adiada ou spam, inclusive ao reabrir
conversation.closed Conversa resolvida A conversa é resolvida
contact.created Contato criado Contato novo, inclusive o que nasce da primeira mensagem num canal
contact.updated Contato atualizado Muda nome, e-mail, telefone, empresa, status, origem do cadastro, foto ou dono da carteira
contact.tag_added Etiqueta adicionada ao contato Uma etiqueta entra no contato (um evento por etiqueta)
order.created Venda registrada Todo pedido registrado: negócio ganho no funil, proposta aceita, venda pela conversa, pedido manual, API, integração ou recorrência
order.status_changed Status do pedido alterado O pedido passa a contar como venda (rascunho para confirmado) ou deixa de contar (confirmado para cancelado ou de volta a rascunho). Rascunho cancelado não dispara
order.delivered Pedido entregue A entrega passa a Entregue, pela tela, por etapa do pedido, por automação ou por integração, inclusive na retirada pelo cliente. Se a entrega sair de Entregue e voltar, dispara de novo
quote.accepted Orçamento aceito A proposta é aceita pelo cliente no link ou registrada pela equipe como aceita. Aceitar de novo a mesma proposta não repete o evento

Não disparam: carga de histórico de uma integração (a primeira importação de pedidos de um ERP, por exemplo), etiquetas que um contato herda numa mesclagem de duplicados e, nos eventos de Vendas, empresa que não usa orçamentos e pedidos.

Como funciona

Criar o endpoint

  1. Clique em Novo endpoint.
  2. Preencha Nome, Descrição (opcional) e URL de destino (só https://).
  3. Marque os eventos na grade, separada em Conversas, Contatos e Vendas. Cada evento mostra o nome, o código e quando dispara.
  4. Clique em Criar webhook e copie o segredo na janela Copie o signing secret agora. Ele não aparece de novo.
  5. Clique em Testar no cartão do endpoint para receber um evento de teste.

Editar muda nome, descrição, URL e eventos, sem trocar o segredo.

Envelope e cabeçalhos

Todo aviso tem o mesmo envelope:

{
  "id": "01K5TXQ3F8Q7ZC1V3W9J2B6M4N",
  "type": "conversation.assigned",
  "created_at": "2026-09-22T16:41:58-03:00",
  "data": { }
}
  • id: identificador da entrega, igual em todas as tentativas automáticas dela. É a chave para não processar duas vezes.
  • type: o evento.
  • created_at: o horário do envio desta tentativa, e não o do fato. Numa nova tentativa, ele muda.

Cabeçalhos: Content-Type: application/json e três próprios, cujos nomes terminam em -Event (o type), -Delivery (o id) e -Signature (a assinatura). Os três nomes completos aparecem em qualquer requisição de teste que o seu servidor receber. Os de assinatura e de entrega também estão no quadro Como funciona, no fim da tela de Webhooks.

O que vem em data

Conversas trazem data.conversation:

{
  "conversation": {
    "id": 4821,
    "status": "open",
    "priority": "medium",
    "channel_type": "whatsapp",
    "contact": { "id": 912, "name": "Ana Souza", "email": "ana.souza@exemplo.com.br", "phone": "5519999999999" },
    "assigned_to": { "id": 7, "name": "Carlos Lima", "type": "user" },
    "created_at": "2026-09-22T16:30:10-03:00",
    "last_message_at": "2026-09-22T16:41:55-03:00",
    "resolved_at": null
  }
}

Contatos trazem data.contact com id, name, email, phone, company_name, status, source, tags (lista de {id, name, color}), created_at e updated_at. O contact.updated acrescenta changed_fields, a lista dos campos que mudaram. O contact.tag_added acrescenta tag, com a etiqueta que acabou de entrar.

Pedidos (order.created, order.status_changed, order.delivered) trazem os campos direto em data:

Campo Conteúdo
id Id do pedido
number Número exibido, como PED-2026-0001
status draft, confirmed ou cancelled
source Origem: manual, conversation, crm, quote, integration ou recurrence
sold_at Data da venda
total_cents Total em centavos
currency Moeda
items_count Quantidade de linhas
contact_id Contato, ou null
delivery_status pending, preparing, ready, shipped, in_transit, delivered ou cancelled

Proposta aceita (quote.accepted) traz em data: quote_id, number (como ORC-00001), version, order_id (o pedido gerado pelo aceite), total_cents (com as escolhas do cliente), contact_id e accepted_by (o nome informado no aceite, que pode vir null).

O que os payloads ainda não trazem

  • order.created chega sem os totais. total_cents, items_count e delivery_status vêm null, e currency quase sempre também. Ao receber o evento, busque o pedido pela API em GET /api/v1/orders/{id} (permissão Ler pedidos e vendas). Os outros dois eventos de pedido chegam com os valores preenchidos.
  • Pedido sem linhas nem pagamento. Nenhum evento de pedido traz os itens ou as parcelas. Também não há evento de pagamento recebido: esse fato existe só como gatilho de Automações.
  • Dono da carteira. Quando a carteira muda, o contact.updated traz assigned_to em changed_fields, mas o payload não diz quem é o novo dono. Busque em GET /api/v1/contacts/{id}.
  • Via do aceite. O quote.accepted não diz se foi o cliente no link ou a equipe que registrou. O mesmo aceite gera também um order.created do pedido novo.
  • Atribuição e status juntos. Se a atribuição e o status (sem ser resolução) mudam no mesmo momento, sai só o conversation.assigned, que já traz o status novo.

Validar a assinatura

O cabeçalho terminado em -Signature vem assim: t=1727034118,v1=5f2c.... Nas 24 horas depois de uma rotação do segredo, vem com duas assinaturas: t=...,v1=<com o segredo novo>,v1=<com o antigo>.

1. Leia o corpo cru da requisição, byte a byte como chegou.
2. Separe o cabeçalho pelas vírgulas. Guarde t e TODOS os v1.
3. Calcule HMAC-SHA256 de  t + "." + corpo_cru , com o segredo inteiro (incluindo whsec_) como chave.
4. Compare, em tempo constante, com cada v1. Aceite se qualquer um bater.
5. Recuse se t estiver a mais de 5 minutos do seu relógio.

Use a comparação em tempo constante da sua linguagem (hash_equals no PHP, crypto.timingSafeEqual no Node.js, hmac.compare_digest no Python).

Resposta esperada

  • Responda com qualquer código 2xx em até 10 segundos. O Codewo marca a entrega como feita.
  • Qualquer outro código, erro de conexão ou demora é falha.
  • O log guarda os primeiros 2 KB da sua resposta, então uma mensagem de erro curta no corpo ajuda a diagnosticar pela tela.

Novas tentativas

Cada entrega tem até 5 tentativas, sempre com o mesmo id:

Tentativa Quando
1ª Na hora do evento
2ª 30 segundos depois da 1ª falha
3ª 5 minutos depois da 2ª falha
4ª 30 minutos depois da 3ª falha
5ª 2 horas depois da 4ª falha

Falhou na 5ª, a entrega é abandonada. No log, a tentativa com nova tentativa agendada aparece como Retentando.

Pausa automática

O endpoint conta as falhas seguidas, de todos os eventos juntos, e zera o contador a cada sucesso. Na 5ª falha seguida, ele é pausado. Com um único evento falhando, isso coincide com a última tentativa dele. Com vários eventos falhando ao mesmo tempo, a pausa pode vir em segundos, antes das novas tentativas.

  • O cartão mostra Pausado (auto) e o aviso "Pausado automaticamente após 5 falhas consecutivas".
  • Quem criou o endpoint recebe o aviso Webhook desativado automaticamente, no app e, conforme as preferências de aviso da pessoa, por e-mail e push.
  • As novas tentativas agendadas que vencerem durante a pausa são descartadas, e os eventos seguintes não são enviados nem guardados.
  • Corrija o servidor e clique em Reativar. O contador volta a zero. Depois de reativar, o que falhou antes da pausa pode ser reenviado uma entrega por vez, em Entregas → Reenviar. O que aconteceu durante a pausa não aparece no log: recupere pela API.

Para suspender de propósito (uma manutenção no seu servidor, por exemplo), use Pausar no menu do endpoint e depois Ativar. Vale a mesma regra: enquanto pausado, nada é enviado.

Rotação do segredo

Use quando o segredo pode ter vazado ou quando alguém que o conhecia deixou a equipe.

  1. No menu do endpoint, clique em Rotacionar secret e confirme.
  2. O segredo novo aparece uma vez, na mesma janela da criação. Copie.
  3. Por 24 horas, todo aviso sai assinado com os dois segredos. Atualize o seu servidor nesse prazo.
  4. Passadas as 24 horas, só o segredo novo assina.

Log de entregas e saúde

  • Números do topo: endpoints ativos, eventos nas últimas 24 horas, taxa de sucesso e falhas nas últimas 24 horas.
  • Barra de saúde no cartão de cada endpoint: as últimas 50 entregas, verde para sucesso e vermelho para falha.
  • Entregas: abre as últimas 100, com filtros Todas, Sucesso, Falhas e Retentando. Cada linha mostra o código de resposta (ou Retentando, quando há nova tentativa agendada), o evento, o número da tentativa a partir da 2ª, o tempo de resposta e o erro, quando houve. Clicando, aparecem o Payload enviado, a Resposta do servidor e o botão Reenviar.
  • Registros com mais de 30 dias são apagados automaticamente.

Reenviar manda o mesmo data como uma entrega nova: id novo e ciclo de tentativas recomeçando do zero.

Excluir (no menu) para o endpoint na hora e tira o histórico de entregas da tela, sem volta.

Pegadinhas comuns

  • Os trechos de exemplo da janela do segredo são só um ponto de partida. Os de PHP e Node.js conferem só a primeira assinatura, que é a do segredo novo, e o de Python dá erro quando chegam duas. Antes de usá-los, ajuste para aceitar qualquer v1, como no roteiro acima. Do contrário, nas 24 horas depois de uma rotação, o servidor que ainda usa o segredo antigo (e, com o trecho em Python, qualquer servidor) recusa as entregas até o endpoint ser pausado.
  • Reenviar com o endpoint pausado não envia nada, mesmo com o aviso de que o reenvio foi enfileirado. Reative primeiro.
  • O código na lista de Entregas não é o id que você recebe. Cada linha da lista identifica uma tentativa. Para cruzar com o log do seu sistema, abra a entrega e procure o id no Payload enviado.
  • O evento de teste usa o primeiro evento marcado, com dados fictícios, ids 0 e "_test": true. Nos eventos de Vendas, o teste chega no formato de contato. Filtre _test no seu sistema para não gravar o teste como dado real.
  • A grade mostra o grupo Vendas mesmo para quem não usa orçamentos e pedidos. Nesse caso, esses eventos nunca disparam.
  • A ordem de chegada não é garantida. Uma nova tentativa pode chegar depois de um aviso mais recente. Quando a ordem importa, busque o estado atual pela API.
  • Só quem criou o endpoint é avisado da pausa. Se essa pessoa sai de férias ou deixa a empresa, a integração pode ficar parada sem ninguém perceber.
  • Corpo convertido quebra a assinatura. Frameworks que transformam o JSON em objeto antes de você ler mudam espaços e a ordem dos campos. Calcule o HMAC sobre o corpo cru.
  • Endereço interno não recebe. O Codewo não alcança localhost nem a rede interna da empresa. Para desenvolver, use um túnel que publique o seu computador num endereço https://.

Boas práticas

  • Endpoint dedicado. Uma URL só para receber os avisos do Codewo, separada das rotas comuns do seu sistema.
  • Receba, valide, enfileire e responda 200. O processamento de verdade fica numa fila do seu lado.
  • Valide a assinatura sempre. Sem ela, qualquer um pode mandar um aviso falso para a sua URL.
  • Deduplique pelo id. Receber o mesmo aviso duas vezes não pode criar dois registros no seu sistema.
  • Trate o aviso como sinal e busque o detalhe pela API quando precisar de dados completos ou do estado mais recente.
  • Monitore do seu lado. Um alerta quando a taxa de erro sobe pega o problema antes da pausa automática.

Veja também

Este artigo foi útil?

Continue lendo