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
string
required
the agent to run — its UUID or its
ua_… handle. agent_id is accepted too.curl
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.
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 three 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.
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.
429 concurrency_limit_exceeded
429 concurrency_limit_exceeded
every concurrent slot is in use. the body carries
active_requests and
limit — queue the caller and retry when a slot frees, or raise your plan
capacity.