Skip to main content
Place outbound calls with bidirectional audio streaming, and retrieve call records. Calls are scoped to your agent identity and span dedicated phone numbers plus shared and dedicated iMessage lines. When you place a call, Inkbox dials the to_number and opens a WebSocket media stream to the client_websocket_url you provide. Your agent connects to that URL to send and receive audio (or text, depending on the pipeline mode). See Media Stream for details on pipeline modes. Alternatively, place the call with mode="hosted_agent" and Inkbox runs Inkbox Voice AI on the call — no WebSocket required.

Place call

Initiate an outbound call. Inkbox dials the to_number and opens a bidirectional media stream to your client_websocket_url.

Request body

Request example

JSON
To place the call from your agent identity’s shared iMessage line, omit from_number — the outbound line is resolved automatically:
JSON
To have Inkbox Voice AI run the call, pass mode and a reason instead of a WebSocket URL:
JSON
Voicemail detection is enabled by default. Set voicemail_detection to "disabled" when your agent should stay connected and leave a message:
JSON
Voice AI inherits the identity’s saved authority when hosted_agent_authority_mode is omitted or null. Set contact_scoped to narrow one call. Set yolo when the call needs identity-wide access to contacts, email, SMS, iMessage, or historical calls:
JSON

Response (200)

JSON
The place call response includes a rate_limit object with your organization’s rolling 24-hour usage snapshot (calls_used, calls_remaining, calls_limit, minutes_used, minutes_remaining, minutes_limit). For shared_imessage_number origination, local_phone_number is null because the shared line is never surfaced. A dedicated_imessage_number call surfaces its dedicated iMessage line as local_phone_number.

Error responses

For iMessage-line originations, actionable placement rejections use these structured 422 details:

Code examples


List calls

List calls for an agent identity, newest first — spans dedicated phone numbers plus shared and dedicated iMessage lines.

Query parameters

Identity-scoped API keys never see contact-rule-blocked calls, regardless of is_blocked. Admin API keys and human sessions see blocked and non-blocked calls by default; use is_blocked=true for an admin-side blocked listing. start_datetime, end_datetime, and tz filter on created_at. Both bounds are optional and non-breaking — omit them for unchanged behavior. See Filtering by date.

Response (200)

JSON

Code examples

The number-scoped listing is deprecated. GET /numbers/{phone_number_id}/calls only returns calls on that dedicated phone number and omits iMessage-line calls. It accepts the same start_datetime/end_datetime/tz date filters for parity. Use GET /calls instead.

Get call

Get a single call by ID across all three call origins.

Path parameters

Response (200)

Returns a call object.

Error responses

Code examples

The number-scoped route is deprecated. GET /numbers/{phone_number_id}/calls/{call_id} cannot address iMessage-line calls. Use GET /calls/{call_id}.

List Voice AI tool activity

List a call’s Voice AI tool activity in execution order. Activity is recorded for both contact_scoped and yolo Voice AI calls. Calls without recorded activity, including older calls and calls driven by your own WebSocket, return an empty page. The response is intentionally safe to display or log. It includes the tool name, execution status, timestamps, and a small result summary. Tool arguments and delivery-system details are not returned.

Path parameters

Query parameters

Response (200)

JSON
status is "started", "succeeded", or "failed". On yolo calls, an accepted write can remain "started" after the call ends while Inkbox finishes it. Poll this endpoint until it reaches a terminal status when completion matters.

Error responses

Code example


Hang up call

End a live call from outside it. The agent on the call can always end it in-band over the media WebSocket; this endpoint is the lever for everything else — tests, operator tooling, or any process that only holds the call ID. It works identically on Inkbox Voice AI calls, where it’s the operator kill switch. The carrier confirms the teardown asynchronously, so the returned call may still show its live status for a moment; the final status, ended_at, and transcript land through the normal call lifecycle (including the call.ended webhook).

Path parameters

Response (200)

Returns the call object as of the hangup request, normally with hangup_reason set to "local". If the call ended on its own at the same moment — the carrier reports it already over before the hangup lands — the request still returns 200, but the call closes with hangup_reason "remote". Don’t branch on hangup_reason to confirm the hangup took effect.

Error responses

Code examples


Call object

Call statuses

Forwarding does not replace the call status. For example, a successfully forwarded call is answered while connected and completed after it ends; its forwarding record retains status: "forwarded".

Forwarding history

Each item in forwardings records one attempt to send the call to another phone or SIP destination. Records are ordered from oldest to newest. "forwarded" is a successful, terminal forwarding outcome. The record remains "forwarded" after the conversation ends; ended_at captures that later event.