Webhook Payloads

View as Markdown

FormantAI sends signed JSON payloads to every active target subscribed to the event.

call.completed

Sent after the call ends and the conversation is saved.

1{
2 "event_id": "evt_1c58c5d8c55a",
3 "event_type": "call.completed",
4 "timestamp": "2026-03-18T20:53:41.766Z",
5 "data": {
6 "call": {
7 "agent_id": 497,
8 "call_parameters": {
9 "customer_name": "Rahul",
10 "loan_id": "LN-12345"
11 },
12 "conversation_id": "e36853de-9cbb-441e-ad75-d3c8ac82abfb_1",
13 "duration_seconds": 142,
14 "ended_at": "2026-03-18T20:55:41.766Z",
15 "failure_reason": null,
16 "from_phone": "+918065177389",
17 "recording_url": "https://api.voice.formantai.com/v1/conversations/e36853de-.../recording",
18 "started_at": "2026-03-18T20:53:41.766Z",
19 "status": "completed",
20 "to_phone": "+917014675791",
21 "trace_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
22 },
23 "results": {
24 "intent": "payment_confirmed",
25 "sentiment": "positive"
26 },
27 "retry": {
28 "attempt_number": 1,
29 "is_final_attempt": true,
30 "max_attempts": 3,
31 "next_retry_at": null
32 },
33 "retry_context": {
34 "collected_data": {
35 "customer_name": "Rahul",
36 "intent": "payment_confirmed"
37 },
38 "retry_initial_message": "Hi Rahul, we spoke earlier about your payment.",
39 "retry_language": "hi-IN",
40 "retry_stage_id": "stage_follow_up"
41 },
42 "transcript": "BOT: Hello Rahul...\nHUMAN: Yes, I can talk."
43 }
44}

call.no_answer

Sent when the call rang but was not answered.

1{
2 "event_id": "evt_4f8bf8gbf88d",
3 "event_type": "call.no_answer",
4 "timestamp": "2026-03-18T20:53:41.766Z",
5 "data": {
6 "call": {
7 "agent_id": 497,
8 "call_parameters": { "customer_name": "Rahul" },
9 "conversation_id": "e36853de-9cbb-441e-ad75-d3c8ac82abfb_1",
10 "duration_seconds": null,
11 "ended_at": "2026-03-18T20:54:11.766Z",
12 "failure_reason": null,
13 "from_phone": "+918065177389",
14 "recording_url": null,
15 "started_at": "2026-03-18T20:53:41.766Z",
16 "status": "no_answer",
17 "to_phone": "+917014675791",
18 "trace_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
19 },
20 "results": {},
21 "retry": {
22 "attempt_number": 2,
23 "is_final_attempt": true,
24 "max_attempts": 3,
25 "next_retry_at": null
26 },
27 "retry_context": null
28 }
29}

call.failed

Sent when call setup fails or the provider cannot connect the call.

1{
2 "event_id": "evt_2d69d6e9d66b",
3 "event_type": "call.failed",
4 "timestamp": "2026-03-18T20:53:41.766Z",
5 "data": {
6 "call": {
7 "agent_id": 497,
8 "call_parameters": { "customer_name": "Rahul" },
9 "conversation_id": "e36853de-9cbb-441e-ad75-d3c8ac82abfb_1",
10 "duration_seconds": null,
11 "ended_at": null,
12 "failure_reason": "provider_error",
13 "from_phone": "+918065177389",
14 "recording_url": null,
15 "started_at": "2026-03-18T20:53:41.766Z",
16 "status": "failed",
17 "to_phone": "+917014675791",
18 "trace_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
19 },
20 "results": {},
21 "retry": null,
22 "retry_context": null
23 }
24}

Field reference

FieldDescription
data.call.agent_idAgent that handled the call.
data.call.call_parametersCall-time parameters from API request or CSV row.
data.call.conversation_idID used to fetch the conversation and recording.
data.call.duration_secondsCall duration in seconds. Null when the call did not connect.
data.call.recording_urlAPI URL to download the recording. Present only when enabled and available.
data.call.trace_idTrace ID returned by call initiation or generated by the platform.
data.resultsStructured outputs extracted by the agent. Shape depends on agent configuration.
data.retryRetry metadata when a retry strategy evaluated this event.
data.retry_contextResume context for future attempts when configured.
data.transcriptFull conversation text. Present only when enabled and available.

Treat results and call_parameters as dynamic objects. Store them as JSON so agent changes do not break your ingestion pipeline.