AI Evy
03/25/2026, 3:47 AMAI Evy
03/25/2026, 3:48 AMjavascript
app.post("/webhook", (req: Request, res: Response) => {
const {event, call} = req.body;
switch (event) {
case "call_started":
console.log("Call started event received", call.call_id) ;
break;
case "call_ended":
console.log("Call ended event received", call.call_id) ;
break;
case "call_analyzed":
console.log("Call analyzed event received", call.call_id) ;
break;
default:
console.log("Received an unknown event:", event) ;
}
// Acknowledge the receipt of the event
res.status(204) .send() ;
}) ;
2. Ensure both your n8n webhook and Retell use the same HTTP method (POST) [(2) ]() .
3. Test locally first using curl before using ngrok [(3) ]() :AI Evy
03/25/2026, 3:48 AMcurl --location 'localhost:8080/webhook' \
--header 'Content-Type: application/json' \
--data '{
"event": "call_ended",
"call": {
"call_type": "phone_call",
"from_number": "+12137771234",
"to_number": "+12137771235",
"direction": "inbound",
"call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
"agent_id": "oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
"call_status": "registered",
"metadata": {},
"retell_llm_dynamic_variables": {
"customer_name": "John Doe"
},
"start_timestamp": 1714608475945,
"end_timestamp": 1714608491736,
"disconnection_reason": "user_hangup",
"transcript": "...",
"opt_out_sensitive_data_storage": false
}
}'
Regarding call outcome data:
The webhook payload includes disconnection_reason in the call object [(1) ]() . To receive only specific events, filter them using the webhook_events field when creating or updating your agent . The default events are call_started, call_ended, and call_analyzed .
Your n8n endpoint must return a successful status code (2xx) within 10 seconds .AI Evy
03/25/2026, 3:48 AMAI Evy
03/25/2026, 3:48 AMMilano
03/25/2026, 3:57 AMAI Evy
03/25/2026, 3:57 AMAI Evy
03/25/2026, 3:57 AMcall_ended event payload looks like this [(2) ]() :
json
{
"event": "call_ended",
"call": {
"call_type": "phone_call",
"from_number": "+12137771234",
"to_number": "+12137771235",
"direction": "inbound",
"call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
"agent_id": "oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
"call_status": "registered",
"metadata": {},
"retell_llm_dynamic_variables": {
"customer_name": "John Doe"
},
"start_timestamp": 1714608475945,
"end_timestamp": 1714608491736,
"disconnection_reason": "user_hangup",
"transcript": "...",
"opt_out_sensitive_data_storage": false
}
}
The test button likely sends a similar sample payload to verify your endpoint can receive and process webhook events correctly [(1) ]() .AI Evy
03/25/2026, 3:58 AMAI Evy
03/25/2026, 3:58 AM