# Call ended

Starts a workflow when a call the AI receptionist answered ends, with the caller's details, the summary, the transcript and the recording link.

Updated Oct 28, 2026. Source: https://smallbusinesschatbot.com/docs/workflows/triggers/call-ended

## What this does

In Small Business Chatbot, this trigger starts a run in every published workflow that uses it, once for each call the AI answering service picks up.

- **Label in the app:** Inbound voice call ended
- **Fires:** When a call the AI receptionist answered ends and its summary is saved
- **Carries:** The fields below, as `{{trigger.…}}`
- **Settings:** None. Its window shows "No settings for this node yet."

## When it fires

- A caller hangs up, or a transfer to your number ends the AI's part of the call. The app writes the summary, saves the call, then starts the runs.
- Calls flagged as likely spam start runs too. `trigger.conversation_record.Is_Spam` tells them apart.
- It fires for calls to your business number. Calls placed by a workflow's [AI voice call](https://smallbusinesschatbot.com/docs/workflows/steps/ai-call) step come to you as a summary email.

## What it carries

| Variable | Type | What it holds |
|---|---|---|
| `trigger.first_name` | text | The caller's first name. Empty when not given. |
| `trigger.phone` | text | The caller's number as its last 10 digits. When the caller gave a clearly different number on the call, that one. |
| `trigger.email` | text | The email the caller gave. Empty when not given. |
| `trigger.action_items` | text | The call summary: what the caller wants and what to do next, written to you |
| `trigger.contact_information_collected` | true or false | `true` when the caller gave a phone number or an email |
| `trigger.recording_url` | text | The call recording, when **Allow voice agent to record calls** is on. Empty on transferred calls. |
| `trigger.twilio_call_sid` | id | The call's id with the phone carrier |
| `trigger.company_name` | text | Your company name as the voice agent has it |
| `trigger.chatbot_url` | text | The address of your assistant |
| `trigger.llm_model` | text | The voice model that answered |
| `trigger.conversation_history_id` | id | The saved call's id |
| `trigger.conversation_type` | text | Always `Voice_Agent` |
| `trigger.date_created` | date and time | When the call was summarised, as `2026-10-27 14:03:11` |
| `trigger.number_of_messages` | number | Turns in the call, both sides |
| `trigger.messages` | list | The transcript. Each message has `role` (`user` for the caller, `assistant` for the AI receptionist) and `content`. |
| `trigger.event_name` | text | Always `inbound_voice_call_ended`. Also in `trigger.event_type` and `trigger.event.name`. |
| `trigger.event_source` | text | Always `inbound_voice_websocket_disconnect` |
| `trigger.public_config_id` | id | Your account's id. Also in `trigger.workspace.public_config_id`. |
| `trigger.conversation.caller_number` | text | The number the call came from |
| `trigger.conversation.business_number` | text | Your number, the one the caller dialled |
| `trigger.conversation.channel` | text | Always `voice` |
| `trigger.contact.*` | object | The CRM contact for the caller. All fields are empty when there isn't one. The fields are listed in [Contact events](https://smallbusinesschatbot.com/docs/workflows/triggers/contact-events#contact-fields). |
| `trigger.voice_agent.*` | object | `assistant_name`, `company_name`, `chatbot_url` and `llm_model` |
| `trigger.summary.*` | object | `first_name`, `phone`, `email`, `action_items` and `contact_information_collected`, grouped |
| `trigger.conversation.*` | object | The call fields above, grouped, plus `phone`, `recording_url` and `twilio_call_sid` |
| `trigger.conversation_record.*` | object | The call as saved, with its original field names |

Three saved fields are useful in an **If** step:

| Variable | Holds |
|---|---|
| `trigger.conversation_record.Is_Spam` | `true` when the call matched your spam keywords |
| `trigger.conversation_record.Human_Transfer_Completed` | `true` when the AI transferred the call |
| `trigger.conversation_record.Human_Transfer_Number` | The number the call went to |

> **Tip:** To skip spam calls, start the workflow with an **If** step: **Left side** `{{trigger.conversation_record.Is_Spam}}`, **Operator** **Equals**, **Right side** `false`. Add the rest of the steps on the TRUE branch.

## The run's contact

- Every answered call starts a run, whatever **Only enrol each contact once** says.
- `trigger.contact` is filled when **Save contacts** is on for **Voice calls** under **CRM › Contacts › Settings**.
- The run gets its contact from a **Find Contact**, **Upsert Contact**, **Add Contact Tag** or **Remove Contact Tag** step, even when `trigger.contact` is filled. Put one early in the workflow so a reply can stop the run with **Stop workflows when contact replies**.

## Example

A trimmed run:

```json trigger
{
  "first_name": "Sam",
  "phone": "4165550188",
  "action_items": "Sam's furnace stopped working. Call him back today.",
  "contact_information_collected": true,
  "recording_url": "",
  "conversation": { "caller_number": "+14165550188", "business_number": "+14165550100", "channel": "voice" },
  "conversation_record": { "Is_Spam": false }
}
```

## Used in

- [Triggers](https://smallbusinesschatbot.com/docs/user-guides/workflows/triggers): how to pick this trigger.
- [Transcripts and summaries](https://smallbusinesschatbot.com/docs/user-guides/voice-agent/transcripts-and-summaries): what the owner gets after each call.
- [HTTP request](https://smallbusinesschatbot.com/docs/integrations/automation/http-request): send the call's details to another tool.
