Calls
Every voice interaction handled by Phone.inc — inbound or outbound, ringing or ended — shows up as a call. The Calls API lets you list recent activity, filter by phone number, direction, or state, pull a single call by its public ID, and run an attended (warm) transfer between employees.
The call model
A call links a business number, a remote party, and (when applicable) the employees who handled it. The full lifecycle is captured in the state field, with timestamps for when the call started and when it was answered.
Properties
- Name
id- Type
- string
- Description
Unique public identifier for the call. Use this when calling the retrieve endpoint.
- Name
from- Type
- string
- Description
The originating phone number in E.164 format.
- Name
to- Type
- string
- Description
The destination phone number in E.164 format.
- Name
direction- Type
- string
- Description
Either
inbound(someone called you) oroutbound(an employee called out).
- Name
state- Type
- string
- Description
The current lifecycle state. See the state values section below for the full list.
- Name
started_at- Type
- timestamp
- Description
ISO 8601 timestamp of when the call was initiated. May be
nullfor calls that haven't started yet.
- Name
answered_at- Type
- timestamp
- Description
ISO 8601 timestamp of when the call was answered.
nullfor missed or rejected calls.
- Name
duration- Type
- integer
- Description
Total length of the call in seconds, measured from
answered_at.nullwhile the call is in progress.
- Name
summary- Type
- string
- Description
Auto-generated summary of the call once it ends.
nullwhile the call is in progress or if a summary hasn't been produced.
- Name
transcription- Type
- string
- Description
Full text transcription of the call recording.
nulluntil the recording has been transcribed.
- Name
transcription_segments- Type
- array
- Description
Speaker-diarized transcription segments. Each entry has
speaker,text, and an optionalemployee_id(the employee's public ID).nulluntil transcribed.
- Name
main_number_id- Type
- string
- Description
The ID of the business number the call was placed to or from.
- Name
main_number_name- Type
- string
- Description
The label of the business number (e.g.
Sales).
- Name
main_number- Type
- string
- Description
The business number in E.164 format.
- Name
main_number_formatted- Type
- string
- Description
The business number formatted for display.
- Name
recording_url- Type
- string
- Description
URL where the call recording can be played or downloaded. New isolated stereo recordings switch to mono MP3s after playback processing; other recordings retain their original channel layout.
nullif recording is disabled or the call hasn't ended yet. The URL is generated per request — don't cache it long-term.
- Name
employees- Type
- array
- Description
Employees who participated in the call. Each entry has
idandname.
- Name
initiated_by- Type
- object
- Description
For outbound calls only — the employee who placed the call. Has
idandname. Omitted on inbound calls.
Call states
The state field walks through the call's lifecycle. The values are:
- Name
initiated- Description
The call has been created but not yet answered. Welcome and menu prompts run in this state.
- Name
queued- Description
The caller is waiting for an available employee. The inbound carrier leg may already be answered so wait audio can play, but
answered_atstays null until an employee picks up. Callers wait in order on that business number; only available employees are rung.
- Name
answered- Description
The call was answered.
answered_atis now set.
- Name
playing_audio- Description
A pre-recorded greeting or message is being played to the caller.
- Name
transferring- Description
The call is being transferred to an employee or another destination.
- Name
recording- Description
The call is being recorded (e.g. taking a voicemail).
- Name
bridged- Description
Two parties are connected and talking. This is the typical state for an active conversation.
- Name
ended- Description
The call has hung up.
durationis now set, and asummarymay follow shortly.
List recent calls
Returns calls for the authenticated employee's company. Without a query, calls are ordered newest first. With a query, calls are ordered using hybrid keyword and semantic search across their transcription and saved caller context, so results can match exact words, customer details, or related topics. By default you get 10 calls; raise that with limit (capped at 50). All filters can be combined.
Optional query parameters
- Name
query- Type
- string
- Description
Search transcribed calls by exact language and semantic similarity. Saved caller context is included when available. Calls without a transcription do not match.
- Name
main_number_id- Type
- string
- Description
Filter to one business number by its public
id.
- Name
phone_number- Type
- string
- Description
Filter to calls involving this phone number on the remote side. Accepts E.164 and best-effort matches local formats too. Combine with
directionto disambiguate inbound vs outbound.
- Name
direction- Type
- string
- Description
Limit results to
inboundoroutbound. Defaults to both.
- Name
state- Type
- string
- Description
Filter by call state, e.g.
endedfor completed calls only. Unknown values are silently ignored.
- Name
limit- Type
- integer
- Description
Maximum number of calls to return. Defaults to 10, capped at 50.
Request
curl -G https://app.phone.inc/api/v1/calls \
-H "X-Api-Key: $PHONE_INC_API_KEY" \
-d query="order status" \
-d main_number_id=0193f4a9-7c34-7c00-9e3d-2b2b8a7f1c01 \
-d direction=inbound \
-d state=ended \
-d limit=25
Response
{
"calls": [
{
"id": "0193f4ba-1234-7c00-9e3d-2b2b8a7f1c11",
"from": "+14085550199",
"to": "+14155551234",
"direction": "inbound",
"state": "ended",
"started_at": "2026-05-11T14:02:11Z",
"answered_at": "2026-05-11T14:02:14Z",
"duration": 187,
"summary": "Customer asked about the status of order #1042.",
"transcription": "Hello, I'm calling about order 1042...",
"transcription_segments": [
{ "speaker": "Caller", "text": "Hello, I'm calling about order 1042.", "employee_id": null },
{ "speaker": "Alex Wong", "text": "Sure, let me look that up for you.", "employee_id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20" }
],
"recording_url": "https://app.phone.inc/rails/active_storage/blobs/redirect/.../recording.mp3",
"main_number_id": "0193f4a9-7c34-7c00-9e3d-2b2b8a7f1c01",
"main_number_name": "Sales",
"main_number": "+14155551234",
"main_number_formatted": "+1 415-555-1234",
"employees": [
{
"id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20",
"name": "Alex Wong"
}
]
}
]
}
Retrieve a call
Returns a single call by its public id. Useful when you receive a webhook or push notification with a call ID and want the latest state. Returns a 404 if the call doesn't exist on this company's account.
Request
curl https://app.phone.inc/api/v1/calls/0193f4ba-1234-7c00-9e3d-2b2b8a7f1c11 \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"id": "0193f4ba-1234-7c00-9e3d-2b2b8a7f1c11",
"from": "+14085550199",
"to": "+14155551234",
"direction": "inbound",
"state": "bridged",
"started_at": "2026-05-11T14:02:11Z",
"answered_at": "2026-05-11T14:02:14Z",
"duration": null,
"summary": null,
"transcription": null,
"transcription_segments": null,
"recording_url": null,
"main_number_id": "0193f4a9-7c34-7c00-9e3d-2b2b8a7f1c01",
"main_number_name": "Sales",
"main_number": "+14155551234",
"main_number_formatted": "+1 415-555-1234",
"employees": [
{
"id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20",
"name": "Alex Wong"
}
]
}
The transfer model
An attended (warm) transfer moves a live call from one employee (the controller) to another without hanging up the customer. The customer is held in the same conference with music while the target rings; after they answer, the controller can complete the handoff or pull the call back, and the target can accept the call to finish the handoff. Call state stays answered — transfer lifecycle lives on the transfer object.
Transfer properties
- Name
id- Type
- string
- Description
Unique public identifier for the transfer.
- Name
state- Type
- string
- Description
One of
ringing,consulting,completed,cancelled, orfailed.
- Name
from_employee- Type
- object
- Description
The controller who started the transfer. Has
idandname.
- Name
to_employee- Type
- object
- Description
The employee being transferred to. Has
idandname.
Transfer states
- Name
ringing- Description
The customer is on hold and the target employee is being rung (up to 30 seconds).
- Name
consulting- Description
The target answered. Controller and target can talk while the customer stays on hold.
- Name
completed- Description
The handoff finished. The original controller left; customer and target stay connected.
- Name
cancelled- Description
The transfer was pulled back or the target never answered. The controller and customer resume.
- Name
failed- Description
The transfer ended because the customer hung up (or the call otherwise failed).
Starting or pulling back a transfer requires an authenticated employee who is the current controller on the call — either via OAuth (mobile/web) or an API key whose creator is that employee. Completing a transfer can be done by that controller or by the employee being transferred to. Only available coworkers can be targeted.
Get the active call
Returns the authenticated employee's currently active call (if any), any open transfer on that call, and coworkers you can transfer to. Also returns a call when the employee is the target of an open transfer (ringing or consulting), even before they have joined. Returns 204 No Content when the employee is idle.
Response fields
- Name
call- Type
- object
- Description
Short call summary:
id,state,direction,from,to.
- Name
transfer- Type
- object
- Description
Open transfer, or
null. Same shape as the transfer model.
- Name
employees- Type
- array
- Description
Coworkers at the company, excluding the authenticated employee. Each entry has
id,name, andstatus(available,on_call,ringing,logged_out, orunknown). Onlyavailablecoworkers can be transferred to.
- Name
available_employees- Type
- array
- Description
Coworkers with status
available. Each entry hasidandname. Same people as theavailablerows inemployees.
Request
curl https://app.phone.inc/api/v1/calls/active \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"call": {
"id": "0193f4ba-1234-7c00-9e3d-2b2b8a7f1c11",
"state": "answered",
"direction": "inbound",
"from": "+14085550199",
"to": "+14155551234"
},
"transfer": null,
"employees": [
{
"id": "0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21",
"name": "Jordan Lee",
"status": "available"
},
{
"id": "0193f4b0-cccc-7c00-9e3d-2b2b8a7f1c22",
"name": "Sam Ortiz",
"status": "on_call"
}
],
"available_employees": [
{
"id": "0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21",
"name": "Jordan Lee"
}
]
}
Start a warm transfer
Starts an attended transfer to another employee. The customer is held in-conference; the target rings for up to 30 seconds.
Missing employee_id returns 400 with error: "invalid_request". Concurrent starts return 409 with error: "transfer_in_progress". An ESL communication failure returns 502 with error: "esl_unreachable"; if cleanup cannot be confirmed, the transfer remains open until its outcome is confirmed. Fetch the active call before retrying.
Required attributes
- Name
employee_id- Type
- string
- Description
Public ID of the coworker to transfer to. Must be
availableand not the current controller.
Request
curl https://app.phone.inc/api/v1/calls/$CALL_ID/transfers \
-H "X-Api-Key: $PHONE_INC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"employee_id":"0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21"}'
Response
{
"transfer": {
"id": "0193f4c0-dddd-7c00-9e3d-2b2b8a7f1c40",
"state": "ringing",
"from_employee": {
"id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20",
"name": "Alex Wong"
},
"to_employee": {
"id": "0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21",
"name": "Jordan Lee"
}
}
}
Complete a warm transfer
Finishes a transfer that is in consulting (or already completed — idempotent). The original controller leaves; the customer and target stay connected. The controller or the employee being transferred to can call this.
Attempting to complete while the target is still ringing returns 409 with error: "transfer_not_consulting" and does not change the transfer.
Request
curl https://app.phone.inc/api/v1/calls/$CALL_ID/transfers/$TRANSFER_ID/completion \
-X POST \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"transfer": {
"id": "0193f4c0-dddd-7c00-9e3d-2b2b8a7f1c40",
"state": "completed",
"from_employee": {
"id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20",
"name": "Alex Wong"
},
"to_employee": {
"id": "0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21",
"name": "Jordan Lee"
}
}
}
Cancel a warm transfer
Pulls the transfer back while it is ringing or consulting. Target legs are dropped and the customer is released from hold to the original controller.
Request
curl https://app.phone.inc/api/v1/calls/$CALL_ID/transfers/$TRANSFER_ID \
-X DELETE \
-H "X-Api-Key: $PHONE_INC_API_KEY"
Response
{
"transfer": {
"id": "0193f4c0-dddd-7c00-9e3d-2b2b8a7f1c40",
"state": "cancelled",
"from_employee": {
"id": "0193f4b0-aaaa-7c00-9e3d-2b2b8a7f1c20",
"name": "Alex Wong"
},
"to_employee": {
"id": "0193f4b0-bbbb-7c00-9e3d-2b2b8a7f1c21",
"name": "Jordan Lee"
}
}
}