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 (min: 1) |
limit | number | 20 | Items per page (max: 100) |
search | string | โ | Search by phone number or party name |
direction | string | all | Filter by call direction: inbound, outbound, internal, all |
status | string | all | Filter by call status: answered, completed, active, failed, no_answer, busy, etc. |
from | string | โ | Filter by caller phone number or username |
to | string | โ | Filter by destination phone number or username |
sentiment | string | all | Filter by AI sentiment analysis: positive, neutral, negative, all |
Responseโ
{
"data": [
{
"id": "call_01h900000000000000000001",
"workspace_id": "ws_123456789",
"number": "18005550199",
"from": {
"name": "Support Agent 1",
"number": "agent1001"
},
"to": {
"name": "Customer",
"number": "14155552671"
},
"status": "completed",
"direction": "outbound",
"duration": 45,
"billsec": 42,
"recording": "ready",
"transcription": "completed",
"sentiment": "positive",
"summary": "Customer reached out to inquire about smart call center solutions.",
"action_items": ["Send Enterprise plan quotation", "Schedule system demo"],
"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. |
stream โ Audio Stream Forkโ
Fork the call audio in real-time to your own WebSocket server. Useful for building custom voice bots, real-time translation, call analytics, or any scenario where your server needs raw audio access during the call.
| Param | Type | Required | Description |
|---|---|---|---|
ws_url | string | โ | Destination WebSocket URL (wss:// or ws://). Must be a publicly accessible server. |
track | string | โ | Audio legs to fork: both (default, stereo โ caller on left, callee on right), inbound (caller only), outbound (callee only). |
sample_rate | number | โ | PCM audio sample rate in Hz: 8000 (default, G.711 compatible) or 16000 (wideband). |
bidirectional | boolean | โ | If true, audio sent from your WS server back to Firetell is played into the call channel in real-time (default: false). |
answer_call | boolean | โ | Answer the call before starting the stream. Default: true. Set to false only if the call was already answered by a prior answer action โ audio will not flow until the channel is answered, regardless of whether the WebSocket connection to your server is established. |
headers | object | โ | Custom HTTP headers to include in the WebSocket handshake (e.g. { "Authorization": "Bearer token" }). Max 10 headers. |
Bidirectional Audio
When bidirectional: true your server receives the caller's raw PCM audio and can send audio frames back in real-time. Firetell injects those frames directly into the caller's audio channel. This lets you build a fully custom voice bot, live interpreter, or real-time TTS system using the transport of your choice.
When bidirectional: false the stream action only sends audio to your server. The call flow continues normally, and your server can consume the audio stream for transcription, recording, or analytics without affecting the call.
bidirectional: true requires the call to be answered.
Firetell only generates audio write frames (needed to play audio back to the caller) on channels that are in the ACTIVE (answered) state. If the call is not answered, your server will receive the connection but audio sent from your server will not be played to the caller.
Always use answer_call: true (the default) when bidirectional: true, or ensure the call was answered by a prior answer action in the flow.
Security notice: Only wss:// and ws:// URLs pointing to publicly routable IP addresses are accepted. Internal addresses (RFC 1918, loopback, link-local, cloud metadata) are blocked.
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"
}
}
]
}'
8. Custom Voice Bot via Audio Streamโ
Fork the call audio in real-time to your own WebSocket server. Your server receives raw PCM audio and can send synthesized speech back into the call channel. This pattern is ideal when you want full control over the AI model, TTS provider, or business logic without using Firetell's built-in Voice Agent.
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": "VoiceBot Support"
},
"to": {
"number": "+84909876543",
"name": "John Doe"
},
"actions": [
{
"action": "stream",
"params": {
"ws_url": "wss://your-bot-server.example.com/call-stream",
"track": "both",
"sample_rate": 8000,
"bidirectional": true,
"headers": {
"Authorization": "Bearer your-api-token",
"X-Bot-Version": "v2"
}
}
}
]
}'
WebSocket protocol on your server side:
| Direction | Frame type | Content |
|---|---|---|
| Firetell โ Your server | Binary | PCM audio at sample_rate Hz (stereo if track=both: caller on left, callee on right) |
| Your server โ Firetell | Binary | Mono PCM audio at sample_rate Hz โ played back to the caller in real-time (requires bidirectional: true) |
| Your server โ Firetell | Text (JSON) | {"type":"killAudio"} โ instructs Firetell to immediately stop any queued audio playback (barge-in) |
call_id, workspace_id, caller_number, caller_name, destination_number, and stream_type=firetell_stream are automatically appended to your ws_url as query parameters so your server can identify the call and caller without needing custom headers.
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) |