POST /v1/webcall starts a call and returns the credentials a browser needs to
join it. the media flows browser ↔ agent directly; it never touches your
servers.
1
start the call on your server
your backend calls
/v1/webcall with your api key and the agent to run.2
pass the credentials to the page
send the
host, token and roomName down to the browser. the token is
short-lived and scoped to this one room.3
join
the page connects with a livekit client and enables the microphone. the
agent greets the caller as soon as it sees them join.
request
exactly one of:string
the agent to run — its UUID or its
ua_… handle. agent_id is accepted too.
needs your api key in Authorization. the call’s id is minted inside this
request: the agent’s before-call tools run with it before you get it back.string
the single-use
wct_ token a register-call returned. it is
the credential on its own — send no api key — and the call starts under the
call_id that response already gave you. access_token is accepted too.response
string
short-lived livekit access token. give it to the browser client; do not reuse
it for a second call.
string
the livekit websocket URL to connect to.
string
the room that was created for this call.
string
the call’s id. it is what shows up in conversations and in your usage, so
store it if you want to correlate a call with your own records later. your
tools receive the same value as
{call_id}. for a registered call it is the
call_id you were already given.knowing the call id first
a one-hop start does everything inside the request: it mints the call’s id, runs the agent’s before-call tools (which receive it as{call_id}), starts
the agent, and only then answers. so if a before-call tool of yours is meant to
look the call up by its id, that request reaches your endpoint before callId
has reached you, and there is nothing yet to match it against.
start such a call in two steps. register it first: that
mints the id and starts nothing. record the id against your own session, then
start the call with the token — the before-call tools run now, under an id
you already hold.
1
register
POST /v1/register-call with your api key. store the call_id it
returns next to whatever your tool will need when it is asked about it.2
start
POST /v1/webcall with { "accessToken": "wct_…" } and no api key. this is
where billing and the before-call tools happen; callId in the response
equals the registered call_id.3
join
as before: hand
host, token and roomName to the page./v1/webcall directly.
joining from the browser
install a livekit client (npm i livekit-client, or the CDN build below) and
connect with the host and token you were given.
ending a call
the call ends when the caller leaves the room —room.disconnect(), closing the
tab, or losing the network. it also ends on its own when it reaches the agent’s
maximum session length, or the length your balance can fund, whichever is
shorter.
you are billed for the seconds the call actually ran. the transcript and
recording land in conversations shortly after it ends.
errors
see the error table. the ones you will meet in normal operation:409 agent_not_deployed
409 agent_not_deployed
the agent was saved but never deployed, so no version is live to answer.
press deploy in the dashboard; nothing is started or billed until you
do. a registered call’s token is spent by this answer: register again
once the agent is deployed.
402 insufficient_balance
402 insufficient_balance
the account cannot fund a usable call. top up, or enable auto top-up in the
dashboard so this does not interrupt live traffic. a registered call’s
token is spent by this answer: register again after topping up.
429 concurrency_limit_exceeded
429 concurrency_limit_exceeded
every concurrent slot is in use. the body carries
active_requests and
limit. for a one-hop start, queue the caller and retry the same request
when a slot frees, or raise your plan capacity. for a registered call the
token is already spent: retry with a fresh /v1/register-call, under the
new call_id it returns.