Call
The Call API allows you to initiate outbound server-to-server calls, control active calls with actions, and retrieve call history.
Endpoints​
| Method | Endpoint | Description |
|---|---|---|
GET | /calls | List call history |
GET | /calls/:id/events | Get call events timeline |
POST | /calls/make | Initiate an outbound call |
PUT | /calls/:id/actions | Update actions on an active call |
List Call History​
Returns paginated call history for your workspace. Requires ApiKey with any scope.
GET /calls?page=1&limit=20
Query Parameters​
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
limit | number | 20 | Items per page |
search | string | — | Search by phone number |
Response​
{
"data": [
{
"call_id": "call_abc123",
"from": "+84901234567",
"to": "+84909876543",
"status": "completed",
"direction": "outbound",
"duration": 45,
"created_at": "2026-07-09T10:00:00Z"
}
],
"meta": {
"total": 100,
"page": 1,
"limit": 20,
"total_pages": 5
}
}
Make a Call​
Initiate an outbound server-to-server call. Requires ApiKey with full scope.
POST /calls/make
Request Body​
| Field | Type | Required | Description |
|---|---|---|---|
to | object | ✅ | Destination party { number, name? }. Number can be an E.164 phone number, extension, or agent username. |
to.number | string | ✅ | Destination phone number (E.164), extension, or username (3-30 chars). |
to.name | string | — | Display name for the callee (up to 64 chars). Fallbacks to to.number if omitted. |
from | object | — | Caller party { number, name? }. Phone number (E.164) or agent username. |
from.number | string | ✅ | Caller ID phone number (E.164) or agent username (3-30 chars). |
from.name | string | — | Display name for the caller / CNAM (up to 64 chars). Fallbacks to from.number if omitted. |
call_flow_id | string | — | Call flow to execute on answer (mutually exclusive with actions). |
max_duration | number | — | Maximum call duration limit in seconds (1 to 7200). The call automatically hangs up after this duration. Default: based on credit & platform safety cap (7200s). |
actions | array | — | Array of actions to perform sequentially when the call connects (mutually exclusive with call_flow_id). |
Auto-Hangup on Flow Completion
When executing sequential actions (e.g. playing an audio announcement or TTS notification), Firetell automatically hangs up the call (NORMAL_CLEARING) as soon as the last action in the list finishes executing. You do not need to explicitly append a hangup or disconnect action unless you want to terminate earlier.
Call Actions​
Each action object has the following shape:
| Field | Type | Required | Description |
|---|---|---|---|
action | string | ✅ | Action type (see below) |
params | object | — | Action-specific parameters |
continue | boolean | — | Whether to continue to the next action |
auto_answer | boolean | — | Auto-answer the call before executing action |
Action Reference​
All server-to-server actions are unified with Call Flow builder actions for structural consistency.
play — Audio Playback​
Play a pre-uploaded workspace audio file.
| Param | Type | Required | Description |
|---|---|---|---|
audio_id | string | ✅ | ID of the workspace audio asset to play |
answer_call | boolean | — | Whether to answer the call before playing. Default: true |
continue_on_play | boolean | — | If true, playback runs in background while the next action executes. Default: false. |
tts — Text-to-Speech​
Play a synthesized speech message.
| Param | Type | Required | Description |
|---|---|---|---|
text | string | ✅ | The text to read aloud |
voice | string | — | Synthetic voice identifier |
speed | number | — | Voice speaking speed rate |
ivr — Wait for Digits​
Wait for the callee to press DTMF keys.
| Param | Type | Required | Description |
|---|---|---|---|
timeout | number | — | Time in seconds to wait for input. Default: 5 |
max_digits | number | — | Maximum digits to collect (between 1-10). Default: 1 |
webhook_url | string | ✅ | The POST destination URL where collected digits will be sent. |
Collected Callback Payload​
When DTMF collection completes (due to timeout, reaching max digits, or pressing #), Firetell dispatches a queued POST request to your webhook_url with the following JSON payload:
{
"event": "call.ivr_collected",
"data": {
"workspace_id": "ws_xyz789",
"call_id": "call_abc123",
"digits": "123",
"status": "completed" // "completed" or "timeout"
}
}
to_operator — Connect External Phone​
Bridge the call to an external phone number or direct SIP URI via carrier gateway.
| Param | Type | Required | Description |
|---|---|---|---|
phone_number | string | ✅ | Destination E.164 phone number or direct SIP URI |
from | string | — | Custom DID phone number (E.164) used as caller ID. Automatically resolves the matching carrier gateway to prevent cross-carrier blockage. Default: Call DID |
timeout | number | — | Timeout in seconds for the ringing phase. Default: 30 |
ringback_audio_id | string | — | Audio file ID to play as hold music while ringing |
connect_agent — Connect Agent​
Bridge the call to a registered Firetell agent.
| Param | Type | Required | Description |
|---|---|---|---|
agent_id | string | ✅ | Unique registered agent ID |
timeout | number | — | Timeout in seconds. Default: 30 |
ringback_audio_id | string | — | Audio file ID to play as hold music while ringing |
connect_team — Connect Team Queue​
Bridge the call to a queue team.
| Param | Type | Required | Description |
|---|---|---|---|
team_id | string | ✅ | Unique registered team ID |
timeout | number | — | Timeout in seconds. Default: 30 |
ringback_audio_id | string | — | Audio file ID to play as hold music while ringing |
connect_voice_agent — Connect Voice AI Agent​
Bridge the call to a Realtime Conversational Voice AI Agent.
| Param | Type | Required | Description |
|---|---|---|---|
voice_agent_id | string | ✅ | Unique Voice Agent ID (va_...) |
version | number | — | Specific agent version number (e.g. 1). Defaults to the current active published version if omitted. |
timeout | number | — | Ringing timeout in seconds before fallback. Default: 30 |
max_duration_seconds | number | — | Maximum duration limit in seconds for the Voice AI session. Default: 300 |
ringback_audio_id | string | — | Audio file ID to play as hold music while establishing connection |
voicemail — Voicemail Recording​
Record a voicemail message from the caller and automatically upload it to Firetell Cloud Storage.
| Param | Type | Required | Description |
|---|---|---|---|
greeting_audio_id | string | — | Pre-recorded greeting file ID. Fallbacks to default greeting if omitted. |
max_duration | number | — | Max recording length in seconds. Default: 60 |
beep | boolean | — | Whether to play a tone beep before starting recording. Default: true |
disconnect / hangup — Hang Up​
Terminate the active call channel. Either name can be used interchangeably.
| Param | Type | Required | Description |
|---|---|---|---|
cause | string | — | SIP hangup reason (default: NORMAL_CLEARING) |
recording — Call Session Recording​
Record the entire call session and automatically upload the file to S3 cloud storage.
This action will be automatically ignored and skipped if the workspace plan quota does not authorize call recording (specifically, call_recording for app-to-phone external calls, or call_internal_recording for app-to-app internal calls). In this case, the call flow will seamlessly proceed to the next action.
| Param | Type | Required | Description |
|---|---|---|---|
format | string | — | Audio format: wav (default) or mp3. |
stereo | boolean | — | Whether to record caller and callee on separate stereo channels (left/right). Default: false. |
answer_call | boolean | — | Whether to answer the call immediately (true, default). Set to false to defer recording until bridged. |
Use Cases & Examples​
1. Simple Outbound Call — Connect to Agent​
Call an external number and connect directly to an agent when answered.
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Customer Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "connect_agent",
"params": {
"agent_id": "agt_abc123",
"timeout": 30
}
}
]
}'
2. Outbound Call with Hold Music​
Call an external number and play hold music while the agent is ringing. The music stops automatically when the agent answers.
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Customer Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "connect_agent",
"params": {
"agent_id": "agt_abc123",
"timeout": 30,
"ringback_audio_id": "aud_holdmusic"
}
}
]
}'
The ringback_audio_id param works on connect_agent, connect_team, connect_voice_agent, and to_operator. Upload your hold music via the Audio API first to get the audio_id.
3. Agent Cascade — Sequential Fallback​
Try agent 1 first. If they don't answer within 10 seconds, automatically try agent 2. If agent 2 also doesn't answer, route to the support team.
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Customer Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "connect_agent",
"params": {
"agent_id": "agt_primary",
"timeout": 10,
"ringback_audio_id": "aud_holdmusic"
}
},
{
"action": "connect_agent",
"params": {
"agent_id": "agt_backup",
"timeout": 10,
"ringback_audio_id": "aud_holdmusic"
}
},
{
"action": "connect_team",
"params": {
"team_id": "team_support",
"timeout": 30,
"ringback_audio_id": "aud_holdmusic"
}
},
{
"action": "voicemail",
"params": {
"greeting_audio_id": "aud_vm_greeting",
"max_duration": 60
}
}
]
}'
Actions execute sequentially. If a connect_* action fails (no answer, timeout, agent offline), the system automatically falls through to the next action in the array.
4. Recorded Outbound Campaign​
Make an outbound call with recording enabled, play a TTS message, then hang up. Useful for automated notification campaigns.
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Customer Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "recording",
"params": {
"format": "wav",
"stereo": false
}
},
{
"action": "tts",
"params": {
"text": "Hello, this is a unified notification from your system."
}
},
{
"action": "disconnect"
}
]
}'
The recording action is automatically skipped if your workspace plan does not include the call_recording quota. The remaining actions will still execute normally.
5. Automated Voice Broadcast / Order Notification​
Make an automated announcement call. The call plays the order status audio file and automatically hangs up as soon as the playback finishes. Setting max_duration: 60 enforces an absolute safety cap of 60 seconds.
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Firetell Delivery"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"max_duration": 60,
"actions": [
{
"action": "play",
"params": {
"audio_id": "au_41817c09bc4d27a405ec5a",
"answer_call": true,
"continue_on_play": false
}
}
]
}'
6. Outbound AI Voice Agent Call​
Initiate an automated outbound call directly connected to a Realtime Voice AI Agent (e.g. appointment confirmation, customer survey, or booking assistant).
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Virtual Clinic Assistant"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"max_duration": 300,
"actions": [
{
"action": "connect_voice_agent",
"params": {
"voice_agent_id": "va_01h900000000000000000001",
"version": 1,
"timeout": 30
}
}
]
}'
7. Mid-Call Action Update​
After a call is in started or active status, you can dynamically push new actions using the Update Call Actions endpoint. This is useful for interactive scenarios where your backend decides the next step based on external logic or customer input.
# Step 1: Initiate the call
curl -X POST "https://{workspace_id}.firetell.app/api/v1/calls/make" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"number": "+84901234567",
"name": "Customer Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "play",
"params": { "audio_id": "aud_welcome" }
}
]
}'
# Returns: { "data": { "call_id": "call_abc123", ... } }
# Step 2: After your backend logic, dynamically hand over the active call to a Voice AI Agent
curl -X PUT "https://{workspace_id}.firetell.app/api/v1/calls/call_abc123/actions" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"action": "connect_voice_agent",
"params": {
"voice_agent_id": "va_01h900000000000000000001"
}
}
]
}'
Response​
All POST /calls/make requests return:
{
"data": {
"call_id": "call_abc123",
"status": "created",
"direction": "outbound",
"from": {
"name": "Customer Support",
"number": "+84901234567"
},
"to": {
"name": "John Doe",
"number": "+84909876543"
},
"job_id": "job_xyz789",
"job_status": "queued"
}
}
Update Call Actions​
Update the actions on an active call. Requires ApiKey with full scope.
The call must be in started or active status, and the media channel must be ready.
PUT /calls/:id/actions
Request Body​
| Field | Type | Required | Description |
|---|---|---|---|
actions | array | ✅ | Array of call action objects (minimum 1). See Action Reference above for available actions and params. |
Example Request​
curl -X PUT "https://{workspace_id}.firetell.app/api/v1/calls/call_abc123/actions" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"action": "tts",
"params": { "text": "Your order has been confirmed. Goodbye!" },
"continue": true
},
{
"action": "disconnect"
}
]
}'
Response​
{
"data": {
"call_id": "call_abc123",
"queued": true,
"action_count": 2
}
}
Get Call Events​
Retrieve the event timeline for a specific call, sorted chronologically. Requires ApiKey with any scope.
GET /calls/:id/events?page=1&limit=50
Response​
{
"data": [
{
"id": "evt_abc123",
"call_id": "call_abc123",
"event": "call.created",
"direction": "outbound",
"sip_code": null,
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"created_at": "2026-07-09T10:00:00Z"
},
{
"id": "evt_abc124",
"call_id": "call_abc123",
"event": "call.ringing",
"direction": "outbound",
"sip_code": null,
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"created_at": "2026-07-09T10:00:02Z"
},
{
"id": "evt_abc125",
"call_id": "call_abc123",
"event": "call.answered",
"direction": "outbound",
"sip_code": 200,
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"created_at": "2026-07-09T10:00:05Z"
},
{
"id": "evt_abc126",
"call_id": "call_abc123",
"event": "call.ended",
"direction": "outbound",
"sip_code": 200,
"hangup_cause": "NORMAL_CLEARING",
"created_at": "2026-07-09T10:00:50Z"
}
],
"meta": {
"total": 4,
"page": 1,
"limit": 50,
"total_pages": 1
}
}
Event Types​
| Event | Description |
|---|---|
call.created | Call channel created |
call.answered | Call was answered |
call.bridged | Two call legs bridged together |
call.ended | Call hangup completed |
call.destroyed | Call channel destroyed |
call.dtmf | DTMF digit received |
call.playback_started | Audio playback started |
call.playback_stopped | Audio playback stopped |
call.recording.started | Call recording stream started (In-Call SSE) |
call.recording.completed | Call recording stream completed (In-Call SSE) |
call.recording.ready | Call recording uploaded and ready (Webhook & SSE) |
call.transcription.dialogue | Live speech transcription utterance (In-Call SSE) |
call.transcription.completed | Call transcription with NER entities (Webhook) |