Skip to main content
A call is one conversation between an agent and a person, on the phone or in a browser. Inbound calls to your numbers and outbound calls you place show up in the same place: GET /v1/calls.

Place a call

The answer is 202 Accepted: the call is created and dialling starts right away. It carries the call’s id (call_…), an ETag and a Location header.

Before a call is placed

The request is refused up front, before anything dials, when:

The lifecycle

lifecycle is where the call is now. Once it reaches completed, failed or canceled it never changes again, and outcome says how it went: terminal_reason adds detail, like remote_hangup or max_duration.
Don’t poll. Subscribe to call.ringing, call.answered and call.ended webhooks instead. See Events.

Read a call

GET /v1/calls/{call_id} returns everything about one call: timings, latency, minutes, analysis, transfers and recordings. Fields with conversation content (summary, caller_name, extracted, unmasked from_e164 and to_e164, recordings) are null or empty unless your key has call:content. Without it, the other party is always masked, like +97150•••4567. Minutes and cost settle shortly after the call ends. Until usage_finalization and cost_finalization say complete, treat those numbers as estimates.

List and filter

Filters include lifecycle, outcome, agent_id, channel (phone or web), direction, attention, since, until, disposition, sentiment, tags, has_recording, talk_ms_min, talk_ms_max, q (search), test_mode and archived (false by default, true or all). Results are newest first; see Pagination. GET /v1/calls/export returns the same filtered list as CSV and needs call:export.

Transcript and recording

Both need call:content. Reading a transcript is recorded in the workspace’s audit log.
Each turn also carries timing (silence_before_ms, stt_latency_ms, llm_ttft_ms, tts_ttfb_ms, end_to_end_ms) for debugging how fast the agent answered. GET /v1/calls/{call_id}/recording returns the audio as audio/wav and supports HTTP range requests, so an <audio> element can seek. Add ?kind=call for the whole call (including transfers and teammates), or ?kind=agent for the agent’s part only. Recordings exist only when the agent has call.record: true. The call.transcript.ready, call.recording.ready and call.analyzed webhooks tell you when each is available.

Cancel or hang up

POST /v1/calls/{call_id}/cancel stops a call that’s still ringing, or hangs up a live one. It needs call:control, an Idempotency-Key and a short reason. If-Match is optional.
The response is 202: the hang-up is queued, and lifecycle moves when the carrier confirms.

Tag, review and annotate

PATCH /v1/calls/{call_id} (needs call:annotate and If-Match) sets tags, attention (none, needs_review, reviewed) and archived. Send only what changes.

Live control

While a call is connected, these act on it: All four need call:read and call:control. The call’s capabilities (can_whisper, can_operate, can_transfer) say which ones work right now for that call.

Live control through the API

Live control acts as a person, so it’s logged under their name. Use a personal key (kbp_live_…): a workspace key gets 403 personal_key_required. The one exception is transferring to the agent’s own approved destinations, which an automation may do with a workspace key, for example when your system decides a VIP caller should reach a manager:
With a teammate’s personal key, tell the agent something mid-call:
Listening in, taking over and transferring phone calls need Kallabot’s call bridge on the line, which is rolling out workspace by workspace. Browser calls support listening in and taking over everywhere. When an action isn’t available, its capability is false and the endpoint answers 409.

Schedule a call for later

POST /v1/scheduled-calls books an outbound call for a set time. Kallabot dials it at that moment, through the same checks as POST /v1/calls.
  • run_at must include a UTC offset (+04:00 or Z), be at least 30 seconds away and within a year.
  • timezone (an IANA name, default UTC) is the callee’s zone, used when showing and moving the call.
  • The agent must be published, and the number is checked against your suppression list when you book and again when it dials.
A scheduled call has a state: If nobody answers (or the line fails), Kallabot tries again a little later, a limited number of times. If a call can’t be dialled near its time at all (for example, every call slot stays busy for 30 minutes), it goes back to proposed so a person can pick a new time rather than ringing someone hours late.

Tool runs and events

  • GET /v1/calls/{call_id}/tool-invocations: every tool the agent used on the call, with its result and timing.
  • GET /v1/calls/{call_id}/events: the call’s full event trail, in order. Page with after_seq. A gap in seq means some events were dropped under load; completeness says so.