Skip to main content
🤖 LLM Friendly: This page is available in raw Markdown format for LLM consumption:call.md|Get full documentation:llms.txt/llms-full.txt

Call

The Call API allows you to initiate outbound server-to-server calls, control active calls with actions, and retrieve call history.

Endpoints​

MethodEndpointDescription
GET/callsList call history
GET/calls/:id/eventsGet call events timeline
POST/calls/makeInitiate an outbound call
PUT/calls/:id/actionsUpdate 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​

ParameterTypeDefaultDescription
pagenumber1Page number
limitnumber20Items per page
searchstring—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​

FieldTypeRequiredDescription
toobject✅Destination party { number, name? }. Number can be an E.164 phone number, extension, or agent username.
to.numberstring✅Destination phone number (E.164), extension, or username (3-30 chars).
to.namestring—Display name for the callee (up to 64 chars). Fallbacks to to.number if omitted.
fromobject—Caller party { number, name? }. Phone number (E.164) or agent username.
from.numberstring✅Caller ID phone number (E.164) or agent username (3-30 chars).
from.namestring—Display name for the caller / CNAM (up to 64 chars). Fallbacks to from.number if omitted.
call_flow_idstring—Call flow to execute on answer (mutually exclusive with actions).
max_durationnumber—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).
actionsarray—Array of actions to perform sequentially when the call connects (mutually exclusive with call_flow_id).
tip

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:

FieldTypeRequiredDescription
actionstring✅Action type (see below)
paramsobject—Action-specific parameters
continueboolean—Whether to continue to the next action
auto_answerboolean—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.

ParamTypeRequiredDescription
audio_idstring✅ID of the workspace audio asset to play
answer_callboolean—Whether to answer the call before playing. Default: true
continue_on_playboolean—If true, playback runs in background while the next action executes. Default: false.

tts — Text-to-Speech​

Play a synthesized speech message.

ParamTypeRequiredDescription
textstring✅The text to read aloud
voicestring—Synthetic voice identifier
speednumber—Voice speaking speed rate

ivr — Wait for Digits​

Wait for the callee to press DTMF keys.

ParamTypeRequiredDescription
timeoutnumber—Time in seconds to wait for input. Default: 5
max_digitsnumber—Maximum digits to collect (between 1-10). Default: 1
webhook_urlstring✅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.

ParamTypeRequiredDescription
phone_numberstring✅Destination E.164 phone number or direct SIP URI
fromstring—Custom DID phone number (E.164) used as caller ID. Automatically resolves the matching carrier gateway to prevent cross-carrier blockage. Default: Call DID
timeoutnumber—Timeout in seconds for the ringing phase. Default: 30
ringback_audio_idstring—Audio file ID to play as hold music while ringing

connect_agent — Connect Agent​

Bridge the call to a registered Firetell agent.

ParamTypeRequiredDescription
agent_idstring✅Unique registered agent ID
timeoutnumber—Timeout in seconds. Default: 30
ringback_audio_idstring—Audio file ID to play as hold music while ringing

connect_team — Connect Team Queue​

Bridge the call to a queue team.

ParamTypeRequiredDescription
team_idstring✅Unique registered team ID
timeoutnumber—Timeout in seconds. Default: 30
ringback_audio_idstring—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.

ParamTypeRequiredDescription
voice_agent_idstring✅Unique Voice Agent ID (va_...)
versionnumber—Specific agent version number (e.g. 1). Defaults to the current active published version if omitted.
timeoutnumber—Ringing timeout in seconds before fallback. Default: 30
max_duration_secondsnumber—Maximum duration limit in seconds for the Voice AI session. Default: 300
ringback_audio_idstring—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.

ParamTypeRequiredDescription
greeting_audio_idstring—Pre-recorded greeting file ID. Fallbacks to default greeting if omitted.
max_durationnumber—Max recording length in seconds. Default: 60
beepboolean—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.

ParamTypeRequiredDescription
causestring—SIP hangup reason (default: NORMAL_CLEARING)

recording — Call Session Recording​

Record the entire call session and automatically upload the file to S3 cloud storage.

caution

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.

ParamTypeRequiredDescription
formatstring—Audio format: wav (default) or mp3.
stereoboolean—Whether to record caller and callee on separate stereo channels (left/right). Default: false.
answer_callboolean—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"
}
}
]
}'
tip

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
}
}
]
}'
info

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"
}
]
}'
caution

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​

FieldTypeRequiredDescription
actionsarray✅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​

EventDescription
call.createdCall channel created
call.answeredCall was answered
call.bridgedTwo call legs bridged together
call.endedCall hangup completed
call.destroyedCall channel destroyed
call.dtmfDTMF digit received
call.playback_startedAudio playback started
call.playback_stoppedAudio playback stopped
call.recording.startedCall recording stream started (In-Call SSE)
call.recording.completedCall recording stream completed (In-Call SSE)
call.recording.readyCall recording uploaded and ready (Webhook & SSE)
call.transcription.dialogueLive speech transcription utterance (In-Call SSE)
call.transcription.completedCall transcription with NER entities (Webhook)