Visão Geral
O webhook de Mudança de Etapa é disparado pela Morada.ai sempre que um deal avança ou retrocede no funil de vendas. O payload inclui dados completos do deal, contato, produto, origem e um resumo da conversa gerado por IA.
Se a opção shouldSendOnlyOnDealTransfer estiver ativada, o webhook será enviado apenas quando o deal for transferido para atendimento humano — ignorando mudanças intermediárias de etapa.
Payload
{
"deal": {
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"status": "active",
"stageCode": "deal_transferred",
"name": "João Silva - Apt 302 Torre A",
"conversationId": "f1e2d3c4-5678-90ab-cdef-1234567890ab",
"partnerId": "b2c3d4e5-6789-01ab-cdef-2345678901bc"
},
"person": {
"id": "c3d4e5f6-7890-12ab-cdef-3456789012cd",
"name": "João Silva",
"email": "joao.silva@email.com",
"phone": "5511999999999"
},
"product": {
"id": "d4e5f6a7-8901-23ab-cdef-4567890123de",
"name": "Edifício Aurora - Torre A"
},
"source": {
"id": "e5f6a7b8-9012-34ab-cdef-5678901234ef",
"code": "whatsapp",
"name": "WhatsApp - Site"
},
"conversationReport": "O lead demonstrou interesse no apartamento de 2 quartos com suíte. Informou renda familiar de R$ 15.000 e tem aprovação de crédito prévia. Solicitou agendamento de visita para o final de semana.",
"appointmentDate": "17-05-2026 14:30",
"metadata": {
"timestamp": "2026-05-13T18:30:00.000Z",
"eventType": "deal_stage_change",
"stageId": "f6a7b8c9-0123-45ab-cdef-6789012345f0"
}
}
Campos
deal
| Campo | Tipo | Descrição |
|---|
deal.id | string | ID único do deal |
deal.status | string | Status atual: active, won, lost |
deal.stageCode | string | Código da etapa atual no funil |
deal.name | string | Nome do deal |
deal.conversationId | string | null | ID da conversa associada |
deal.partnerId | string | ID do parceiro |
person
| Campo | Tipo | Descrição |
|---|
person.id | string | ID único do contato |
person.name | string | null | Nome completo |
person.email | string | null | E-mail |
person.phone | string | null | Telefone com DDI (ex: 5511999999999) |
product
O campo product só é enviado quando o deal possui um produto/empreendimento associado.
| Campo | Tipo | Descrição |
|---|
product.id | string | ID do produto/empreendimento |
product.name | string | Nome do produto/empreendimento |
source
| Campo | Tipo | Descrição |
|---|
source.id | string | ID da origem |
source.code | string | Código da origem (ex: whatsapp, instagram, web) |
source.name | string | Nome descritivo da origem |
Outros campos
| Campo | Tipo | Descrição |
|---|
conversationReport | string | null | Resumo da conversa gerado por IA — contém os principais pontos discutidos, dados coletados e intenções identificadas |
appointmentDate | string | null | Data do agendamento associado, se houver. Formato: dd-MM-yyyy HH:mm (horário de Brasília) |
metadata.timestamp | string | Data/hora do envio do webhook (ISO 8601) |
metadata.eventType | string | Sempre "deal_stage_change" |
metadata.stageId | string | ID da nova etapa no funil |
Exemplo de uso
app.post("/webhook/morada", (req, res) => {
const { deal, person, conversationReport, metadata } = req.body;
console.log(`Deal ${deal.id} movido para etapa ${deal.stageCode}`);
console.log(`Contato: ${person.name} (${person.phone})`);
if (conversationReport) {
// Salvar resumo da conversa no seu CRM
console.log(`Resumo IA: ${conversationReport}`);
}
res.status(200).json({ received: true });
});
Resposta esperada
Retorne um status HTTP 200 para confirmar o recebimento:
Se o seu endpoint retornar um status diferente de 2xx ou não responder dentro do timeout, a Morada.ai poderá tentar reenviar o evento. Implemente idempotência para lidar com entregas duplicadas.