Skip to content
AISARAISAR
Calls

Calls

Call missed

call.missed

Fires when a call ends without being answered — an inbound call the operator did not pick up, or an outbound call the customer did not accept. Answered calls emit call.completed instead.

HTTP request

AISAR sends a signed POST request to your webhook_url:

http
POST {webhook_url}
Content-Type: application/json
X-AISAR-Signature: sha256=...

{
  "event": "call.missed",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-06-06T12:00:30.000000Z",
  "company_id": 1,
  "data": {
    "call_id": 124,
    "direction": "inbound",
    "status": "missed",
    "from_number": "12025550187",
    "to_number": "12025550187",
    "contact_id": 42,
    "conversation_id": 100,
    "channel_id": 5,
    "external_call_id": "wacall_def456",
    "duration_sec": null,
    "started_at": "2026-06-06T12:00:00+00:00",
    "answered_at": null,
    "ended_at": "2026-06-06T12:00:30+00:00",
    "routing": {
      "scheme_id": 7,
      "scheme_name": "Основная линия",
      "ivr_selections": [],
      "final_step": { "type": "voicemail", "node_id": "n_vm", "result": "offered" },
      "answered_by": null,
      "path": [
        { "seq": 1, "node_id": "n_hours", "type": "schedule", "result": "off", "at": "2026-06-06T12:00:00+00:00" },
        { "seq": 2, "node_id": "n_menu", "type": "ivr_menu", "result": "no_input", "attempt": 1, "at": "2026-06-06T12:00:12+00:00" },
        { "seq": 3, "node_id": "n_menu", "type": "ivr_menu", "result": "no_input", "attempt": 2, "at": "2026-06-06T12:00:20+00:00" },
        { "seq": 4, "node_id": "n_vm", "type": "voicemail", "result": "offered", "at": "2026-06-06T12:00:20+00:00" }
      ],
      "truncated": false
    }
  }
}

The X-AISAR-Signature header carries an HMAC-SHA256 signature of the request body — use it to verify the request came from AISAR.

Example payload

json
{
  "event": "call.missed",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-06-06T12:00:30.000000Z",
  "company_id": 1,
  "data": {
    "call_id": 124,
    "direction": "inbound",
    "status": "missed",
    "from_number": "12025550187",
    "to_number": "12025550187",
    "contact_id": 42,
    "conversation_id": 100,
    "channel_id": 5,
    "external_call_id": "wacall_def456",
    "duration_sec": null,
    "started_at": "2026-06-06T12:00:00+00:00",
    "answered_at": null,
    "ended_at": "2026-06-06T12:00:30+00:00",
    "routing": {
      "scheme_id": 7,
      "scheme_name": "Основная линия",
      "ivr_selections": [],
      "final_step": { "type": "voicemail", "node_id": "n_vm", "result": "offered" },
      "answered_by": null,
      "path": [
        { "seq": 1, "node_id": "n_hours", "type": "schedule", "result": "off", "at": "2026-06-06T12:00:00+00:00" },
        { "seq": 2, "node_id": "n_menu", "type": "ivr_menu", "result": "no_input", "attempt": 1, "at": "2026-06-06T12:00:12+00:00" },
        { "seq": 3, "node_id": "n_menu", "type": "ivr_menu", "result": "no_input", "attempt": 2, "at": "2026-06-06T12:00:20+00:00" },
        { "seq": 4, "node_id": "n_vm", "type": "voicemail", "result": "offered", "at": "2026-06-06T12:00:20+00:00" }
      ],
      "truncated": false
    }
  }
}

Payload fields

FieldTypeDescription
call_idintegerInternal call ID (stable across all lifecycle events of this call)
directionstringinbound (from contact) or outbound (placed by operator)
statusstringCall status: missed
from_numberstringCaller number. For inbound calls — the customer; for outbound — your WhatsApp Business number
to_numberstringCallee number. For inbound calls — your WhatsApp Business number; for outbound — the customer
contact_idinteger|nullContact ID
conversation_idinteger|nullConversation ID
channel_idintegerWhatsApp Business channel ID
external_call_idstring|nullProvider-specific call ID (WhatsApp/SIP)
duration_secnullAlways null (no talk time)
started_atstring|nullISO 8601 timestamp the call started ringing
answered_atnullAlways null (the call was never answered)
ended_atstringISO 8601 timestamp the call ended
routingobject|nullHow the call travelled through the inbound call scheme: menu presses, final step, who answered and the full path. null if the call did not go through a scheme
routing.scheme_idinteger|nullID of the scheme the call went through
routing.scheme_namestring|nullScheme name at the time of the call
routing.ivr_selectionsarrayAccepted voice-menu key presses, in order. Invalid presses and silence are not listed here, they appear in path. Empty array if there was no menu
routing.ivr_selections[].menu_node_idstring|nullMenu node identifier at the time of the call
routing.ivr_selections[].digitstring|nullThe pressed digit
routing.ivr_selections[].labelstring|nullMenu item label (the edge label in the scheme), if set
routing.ivr_selections[].attemptinteger|nullMenu attempt number, starting at 1 (the menu may repeat)
routing.ivr_selections[].atstring|nullTime of the press, ISO 8601
routing.final_stepobject|nullThe last meaningful routing step: ring_group, responsible_manager, queue, ai_agent, voicemail, transfer or ai_escalation. A hangup step is reported here only if nothing meaningful came before it. Same shape as a path item, without seq and at
routing.answered_byobject|nullWho answered: { assignee_type, user_id }. assignee_type is operator or ai_agent; user_id is set for an operator. null if nobody answered (always for call.missed)
routing.patharrayFull walk through the scheme, at most 50 steps. A step has seq (from 1), node_id (node identifier at the time of the call; null for steps outside the graph), type, result, at (ISO 8601) and optional digit, attempt, label, team_ids, operator_ids, reason, from_user_id, to_user_id. type and result pairs: schedule: work | off; client_check: known | new; play: played | skipped; ivr_menu: digit | invalid | no_input | skipped; ring_group: offered; responsible_manager: offered | no_target; queue: offered | timeout; ai_agent: offered | failed | escalated | no_answer; voicemail: offered; hangup: hangup (reason carries the cause); transfer: transferred (from_user_id, to_user_id); ai_escalation: handed_to_operator (to_user_id)
routing.truncatedbooleantrue if the path hit the 50-step ceiling and later steps were not recorded