API reference
Agents API
An agent bundles a system prompt with a provider/model choice for each of STT, LLM, and TTS. All endpoints require an API key or dashboard token and are scoped to the caller's account — you only ever see/modify your own agents.
Create an agent
POST /agents
Body:
{
"name": "Support bot",
"system_prompt": "You are a helpful support agent for Acme...",
"llm_provider": "llmgateway",
"llm_model": "gpt-oss-120b",
"stt_provider": "groq",
"stt_model": "whisper-large-v3-turbo",
"tts_provider": "groq",
"tts_voice": "autumn",
"temperature": 0.7,
"interruption_enabled": true,
"interruption_sensitivity": 0.5,
"endpointing_sensitivity": 0.5,
"language_lock": null,
"model_tier": "balanced",
"latency_profile": "balanced"
}
All fields except name, system_prompt, and tts_voice have defaults (llm_provider: "llmgateway", stt_provider: "groq" / stt_model: "whisper-large-v3-turbo", tts_provider: "groq", temperature: 0.7, plus the realtime knobs below) — llm_model and tts_voice are always required since they're provider-specific.
Returns 201 with the full agent object (adds id, created_at, updated_at).
List agents
GET /agents
Returns an array of your agents, newest first.
Get an agent
GET /agents/{agent_id}
404 if the agent doesn't exist or belongs to a different account.
Update an agent
PATCH /agents/{agent_id}
Body: any subset of the POST /agents fields (including the realtime knobs below) — only fields you include are changed.
Realtime pipeline knobs
Every knob has a sane default, a documented range, and is validated on create/update (422 for an out-of-range or unknown value). Existing agents keep their prior behaviour — each column has a server default.
| field | type | default | range / values | effect |
|---|---|---|---|---|
interruption_enabled | boolean | true | — | whether the caller talking over the agent cuts it off (barge-in) |
interruption_sensitivity | number | 0.5 | 0.0–1.0 | higher = a fainter/shorter caller utterance interrupts |
endpointing_sensitivity | number | 0.5 | 0.0–1.0 | higher = a shorter pause counts as the caller's turn ending |
language_lock | string / null | null | "en", "fr", or null | locks batch STT to that language and adds a "always speak X" instruction for realtime; null = auto-detect |
model_tier | string | "balanced" | "fast", "balanced", "quality" | for realtime calls, takes effect only when set to a non-balanced value (otherwise the agent's explicit llm_model wins). The batch LLM API accepts the same tier names directly, independent of any agent |
latency_profile | string | "balanced" | "low", "balanced", "quality" | advisory; surfaced to the client in the WebSocket call_config frame |
On WebSocket connect the server now sends one extra JSON frame with these values — see The talk WebSocket. It's additive: existing clients that ignore unknown frame types are unaffected.
Delete an agent
DELETE /agents/{agent_id}
Returns 204. Deleting an agent does not delete its past calls/messages.
Providers and models
llm_provider/stt_provider/tts_provider must be one of the values GET /providers returns (the dashboard's agent editor reads from the same endpoint, so it always matches what's configurable). As of writing:
| Component | Providers |
|---|---|
| LLM | llmgateway (routes to whatever chat model you pick — GPT, Claude, Gemini, Mistral, and others, by model id) |
| STT | groq, voxtral, elevenlabs, deepgram — voxtral, elevenlabs, and deepgram also support speaker diarization in the batch STT API |
| TTS | groq, inworld, edge, elevenlabs, deepgram, voxtral |
Sending an unknown provider on create/update returns 400. Fetch GET /providers for the live, current model/voice catalog per provider rather than hardcoding it — LLM models in particular are fetched live from the LLM gateway and change over time.