The widgets are drop-in bubbles for a website. When you are building a product around a voice call — an AI interviewer, an in-app copilot, a guided intake flow — you need your own UI: your own buttons, your own transcript pane, your own loading and error states. That is what the Web SDK is for.
How a web call starts
A web call is registered first, then joined — the same shape as creating a phone call:
POST /v2/create-web-call registers the call and returns an access_token, the livekit_url to connect to, and a call_id.
- The browser joins with
OpenMicWebClient.startCall.
In production, call create-web-call from your backend so you decide who
can start calls and with which variables. For prototypes you can call it
straight from the browser with your public key (omic_pub_...).
Quickstart
dynamic_variables are substituted into the agent prompt wherever it references {{candidate_name}} or {{role}}, so one durable agent serves every call with per-call context — no need to create an agent per call. customer_id is your own identifier; it comes back on the call record and the post-call webhook so you can attribute the call to the session that started it.
Live transcript and call state
Transcription is on by default for every web call — partial segments stream in as each side speaks, so captions render live rather than at the end of each turn.
Controls
startCall also accepts sampleRate, captureDeviceId, playbackDeviceId, and emitRawAudioSamples (which streams raw Float32Array agent audio via the audio event, for visualizations).
After the call
The call_id from create-web-call is the same id used by the calls API, so post-call retrieval needs no correlation tricks:
If the agent has a post-call webhook configured, web calls fire it too, with dynamicVariables (including anything you passed at start) echoed in the payload.
Managing agents from code
OpenMicClient also wraps agent CRUD — use it server-side with a private key:
Script tag (no build step)
Never put a secret key (omic_...) in browser code. Use the public key
(omic_pub_...) client-side, or better, register calls from your backend.
See Public API key.