Skip to content
Inkbox

Inkbox

DocsPricingBlogContact
GuidesAPI ReferenceChangelog

Ctrl K

GuidesAPI ReferenceChangelog

Jump to

Hosted call agent

Handling a phone call normally means running a WebSocket server: Inkbox dials or answers, connects to your client_websocket_url, and streams audio both ways (see Media Stream). The hosted call agent removes the socket entirely. Inkbox runs an opinionated realtime voice agent on the platform side — it answers (or places) the call, knows who it's talking to, can read your agent's full history with that one person, can text or email them mid-call, records action items, and hands your agent a structured package when the call ends.

Zero setup: provision a number, flip one setting, and the number answers. No code, no socket, and no webhook required — the call.ended webhook is optional output, never required input.

There are exactly two ways to put a brain on a call:

  • Hosted call agent — zero setup, run by Inkbox, opinionated, with a fixed built-in toolset. This page.
  • Bring your own — full control over the audio via client_websocket_url and the media stream. Everything documented elsewhere in the Phone docs.

Pick per call (outbound), or per identity or per number (inbound). The two tiers never mix on a single call.

The hosted-agent surface is available in the API, the SDKs, and the CLI from SDK 0.4.22.

Answering calls

Set the identity's incoming-call action to hosted_agent. It's the only answering action with zero prerequisites — no WebSocket URL, no webhook URL:

The same value is accepted when configuring a single number (PATCH /phone/numbers/{phone_number_id}, or inkbox number update --incoming-call-action hosted_agent). The number-level PATCH merges: any stored client_websocket_url or incoming_call_webhook_url is kept but ignored while the action is hosted_agent. The identity-level action set (the snippet above) replaces the whole inbound-call config — omitted URLs are cleared, so if you later switch back to auto_accept or webhook, supply the URL again in that call.

Inbound protections run before the agent picks up: contact rules and usage quotas apply exactly as they do for every other action — the hosted agent only answers calls that would have been deliverable anyway.

Placing calls

Give the agent an errand: place a call with mode="hosted_agent" and a plain-language reason describing what the call is for.

The reason becomes the agent's task brief for the call: it introduces itself, works the errand, records what happened as post-call action items, and ends the call politely. A failed errand is never silent — whatever happens, you get the post-call package.

Two shape rules, enforced with a 422: mode="hosted_agent" requires a non-empty reason (up to 2,000 characters) and must not carry a client_websocket_url; reason is only valid with mode="hosted_agent". Everything else about placing a call — origination, caller ID rules, rate limits — is unchanged; see the place call reference. Two 503s are possible on hosted calls only: hosted_agent_unavailable when the hosted call agent isn't available, and hosted_agent_at_capacity when hosted capacity is momentarily saturated — retry the latter shortly.

mode works with any origination, so the hosted agent can call over a dedicated number or the identity's iMessage line alike.

Configuring the agent

Each identity carries an optional hosted-agent configuration: a voice, a model, and free-form instructions (up to 8,000 characters) that steer how the agent behaves on that identity's calls. All three are nullable — a null field means the platform default applies, and the defaults are sensible, so most identities need no configuration at all.

Under the hood this is GET/PUT /phone/hosted-agent-config. Writes are full-replace: every omitted or null field resets to the platform default. Identity-scoped API keys resolve their own identity; with an admin API key, or when managing from the Inkbox Console, pass agent_identity_id.

Custom instructions are layered on top of everything the agent already knows, so they can steer tone, boundaries, and priorities without you restating the basics. The agent treats them as standing orders from you, applied on every call — with one carve-out: on an outbound errand, the call's reason takes precedence if the two conflict, so a standing quirk can't hijack the task the call was placed for.

What the agent knows

Every hosted session is briefed at answer time — no lookups required from your side:

  • Its own identity — the agent's display name, handle, email address, and which line the call is on.
  • Who it's talking to — the counterparty's contact card (name, company, notes, known numbers and emails), resolved by the number on the call. Unknown callers work fine; the agent simply greets them neutrally.
  • Your history with them — per-channel interaction counts across calls, texts, iMessage, and email, including activity in the last 24 hours and the most recent interaction on each channel. The agent checks history before asking things the caller may have already told you.
  • Their connection state — whether the caller is opted in to SMS, and whether they're connected over iMessage — so the agent offers follow-ups on channels that will actually work, and can walk them through connecting where they aren't.
  • The local time — the call clock runs in the counterparty's timezone, inferred from the phone number (stated as approximate), so "tomorrow morning" means what the caller means.
  • The task brief — on outbound hosted calls, your reason.

What the agent can do

The agent's capabilities are fixed and identical on every hosted call — there is no per-customer tool configuration, and nothing it can do takes a recipient: everything is bound server-side to the person on the call. Sends go through the same pipeline as any other Inkbox send: SMS opt-outs, contact rules, and delivery tracking all apply exactly as if your own code had sent the message.

On a call, the agent can:

  • Recall your history with the caller — past calls (including reading a previous call's transcript), SMS, iMessage, and email threads, plus keyword search across all of them. Every lookup covers only the person on the call.
  • Text, iMessage, or email the caller mid-call — an SMS goes out from the identity's own number, an iMessage over its iMessage line, and an email from its own address (known contacts with an email on file only). It reports delivery honestly: confirmed, still on its way, or failed and why.
  • Record work for your agent — register, refine, or withdraw post-call action items during the call; the open items become the post-call package.
  • Answer "what is Inkbox?" — it can consult the public Inkbox docs and offer to text a relevant link rather than reading URLs aloud.
  • Check live state and end the call — re-check the caller's connection state mid-call (e.g. to confirm "your message just came through"), and hang up once the caller signals they're done.

What it can't do

Scoping is by construction, not by policy. No capability takes a recipient — the person on the call is bound server-side when the session starts, so the agent is physically incapable of texting, emailing, or reading history about anyone else, even if a caller tries to talk it into it. It cannot browse your contacts, touch other conversations, or reach any other Inkbox data.

It also doesn't run custom tools. If your agent needs to hit your systems mid-call, that's the bring-your-own tier: take the call over client_websocket_url and drive it yourself. For everything that can wait until the call ends, post-call action items cover it — the hosted agent records the work, and your agent executes it from the call.ended delivery.

The post-call package

Every hosted call ends in a single call.ended delivery carrying the whole story: the call record (now with mode and reason), the transcript, an outcome, and the recorded post_call_action_items — atomically, in one event. A hosted call reports back on every terminal state, inbound and placed alike — even when nobody picked up, outcome says what happened — so an errand can't fail silently.

outcomeMeaning
completedThe call connected and ran to a normal end. A call that reaches voicemail also reports completed — the transcript shows what happened
no_answerThe call was never answered — an outbound call rang out, or an inbound caller hung up before the agent picked up
declinedThe call was rejected, or the line was busy
failedThe hosted session hit an error and the call was torn down, or the call could not be completed at all — e.g. an undeliverable destination

outcome is null on client_websocket calls — it describes hosted sessions only, and it rides the call.ended payload as data.outcome.

Action items arrive as an ordered list on the same event, as data.post_call_action_items:

JSONJSON

Each item carries a seq (its 1-based order), an action title, optional details, and a status of "open". Actions the agent canceled mid-call are dropped — only open items ride the payload. The call.ended event is the one atomic delivery of the whole package (outcome lives only there); like every webhook it carries a stable ID and is replayable, so a missed delivery can be re-fetched rather than lost. The open action items are additionally readable straight off the call object as post_call_action_items, so they can be looked up any time without replaying the event.

Watching and stopping a live call

You keep two levers while a hosted call is in progress:

Inkbox

Copyright © 2026 Inkbox

This site is protected by reCAPTCHA.

Google Privacy Policy and Terms of Service apply.

Website

Inkbox

Copyright © 2026 Inkbox

This site is protected by reCAPTCHA.

Google Privacy Policy and Terms of Service apply.

Website

Y CombinatorBacked by Y Combinator
Hosted call agent