Webhooks e eventos
Os webhooks da conta enviam o que acontece em toda a sua conta para uma URL que você escolhe, na hora: um lead novo, uma reunião agendada, um negócio mudando de etapa. São eles que as integrações com Zapier e n8n usam por baixo, e você também pode apontá-los para o seu próprio endpoint.
Eles se somam ao webhook do projeto da página Respostas de um e-mail, que continua funcionando como antes. Um webhook do projeto cobre as interações de um único e-mail. Um webhook da conta cobre todos os e-mails, mais os eventos abaixo, e é assinado do mesmo jeito.
Adicionar um webhook
- Vá em Desenvolvedores no painel e encontre o cartão Webhooks.
- Informe a URL do endpoint (uma URL
https://pública) e marque os Eventos que quiser. - Clique em Adicionar webhook e copie o segredo de assinatura. Ele só aparece desta vez.
Cada webhook mostra como foi criado (Painel, API, Zapier ou n8n), o status e a última entrega. Enviar teste envia um exemplo do evento escolhido, com "test": true no data. Excluir remove o webhook. Uma conta pode ter até 50.
Só o dono da conta pode adicionar ou excluir webhooks, e talvez seja preciso entrar de novo antes.
Eventos
| Evento | Dispara quando |
|---|---|
interaction.received | Um destinatário interage com um e-mail: um voto, uma avaliação, uma resposta de quiz, um clique rastreado, uma compra e assim por diante. Repetições deduplicadas não disparam. |
form.submitted | Um formulário dentro de um e-mail é enviado (source: "email-form"), ou um formulário de inscrição (source: "signup-form"). |
contact.created | Um contato é adicionado a uma lista. |
contact.updated | Os campos de um contato mudam. Salvar dados idênticos não dispara. |
lead.hot | A pontuação de engajamento de um contato cruza, subindo, o seu limite de lead quente. |
lead.new | Um lead novo chega por um formulário de inscrição ou por um formulário dentro de um e-mail. |
booking.created | Uma reunião é agendada. |
booking.cancelled | Um agendamento é cancelado, com cancelledBy. Remarcar não dispara nenhum dos dois eventos de agendamento. |
deal.created | Um negócio é criado, de qualquer origem: o quadro, uma regra automática, uma jornada, uma proposta ou a API. |
deal.stage_changed | Um negócio muda de etapa, incluindo ganho e perdido. |
purchase.completed | Um destinatário paga por um checkout dentro do e-mail. |
journey.completed | Um contato chega ao fim de uma jornada. Quem sai antes não conta. |
Os eventos de contato disparam com importações, formulários de inscrição, a API, sincronizações e conectores de IA. Uma única gravação de mais de 500 contatos (uma importação CSV grande, por exemplo) não dispara nenhum, para que uma importação não inicie milhares de fluxos. Edições na grade de contatos, etapas de jornada Atualizar campo e respostas salvas também não disparam.
lead.hot e lead.new disparam independentemente dos interruptores e limites dos seus alertas de leads: assinar já é o consentimento.
Payload
Toda entrega é um POST JSON com o mesmo envelope:
{
"id": "evt_8c1f…",
"type": "deal.stage_changed",
"createdAt": 1790000000000,
"data": {
"deal": {
"id": "deal_abc123",
"title": "Annual plan",
"value": 1200,
"currency": "USD",
"pipelineId": "owner_default",
"stageId": "proposal-sent",
"stage": "Proposal sent",
"status": "open",
"source": "manual",
"listId": "list_abc123",
"rowId": "3f6c1b0e2d…",
"email": "[email protected]"
},
"fromStageId": "meeting-booked"
}
}
id é o mesmo em cada entrega de um mesmo evento e também vai no cabeçalho X-MailInApp-Idempotency-Key, então você pode descartar com segurança uma reentrega que já processou. createdAt está em milissegundos epoch.
Para ver o data de cada tipo de evento, chame GET /api/v1/events/sample ou use Enviar teste.
Verificar a assinatura
As entregas trazem os cabeçalhos X-MailInApp-Timestamp e X-MailInApp-Signature, calculados exatamente como no webhook do projeto. Verifique-os sobre o corpo bruto com o seu segredo de assinatura e rejeite timestamps de mais de alguns minutos atrás. A documentação do webhook do projeto traz uma função Node.js pronta.
Novas tentativas
O seu endpoint tem 5 segundos para responder com um 2xx. Qualquer outra coisa (tempo esgotado, status de erro, redirecionamento) é uma falha, e a entrega é tentada de novo automaticamente, com intervalos crescentes ao longo de várias horas, com o mesmo corpo e a mesma chave de idempotência, para a URL atual do webhook. Responda rápido e faça o trabalho demorado depois.
- Se o seu endpoint responder
410 Gone, o webhook é desativado. É assim que clientes REST Hooks cancelam a assinatura. - Revogar uma chave de API desativa os webhooks criados com ela.
- Excluir um webhook interrompe as novas tentativas pendentes.
Assinar pela API
Zapier, n8n e o seu próprio código podem gerenciar webhooks com uma chave de API (Authorization: Bearer mia_live_…):
curl https://mailinapp.com/api/v1/webhooks \
-H "Authorization: Bearer mia_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://hooks.example.com/mailinapp", "events": ["lead.hot", "booking.created"]}'
A resposta 201 traz o id da assinatura e o secret dela, que assina cada entrega. Guarde-o: ele não é devolvido de novo. GET /api/v1/webhooks lista as suas assinaturas, e DELETE /api/v1/webhooks/{id} remove uma. Um único nome de evento desconhecido faz a requisição inteira ser recusada. Essas rotas aceitam 30 requisições por minuto por chave.
O contrato completo está na especificação OpenAPI.