API reference
Base URL https://<your-app>/api/v1. Authenticate with Authorization: Bearer cv_live_… — keys are per workspace, created in Settings → API keys and shown once. Requests and responses are JSON.
Agents
An agent is one company voice in one role. Its configuration is an AgentSpec — create one from a role template and override what you need.
GET/api/v1/agents
List agents in the workspace.
POST/api/v1/agents
Create an agent from a role template.
{
"name": "Front desk",
"role": "receptionist",
"company": { "name": "Acme Dental", "description": "Family dental practice in Zurich" },
"spec": { "voice": { "engine": "auto", "language": "de" } }
}{ "id": "…", "status": "draft", "version": 1 }GET/api/v1/agents/{id}
Fetch one agent with its AgentSpec.
PATCH/api/v1/agents/{id}
Update name, status (draft | live | paused) or spec. Bumps the version.
Calls
Outbound calls pass the compliance gate first. Outside the callee’s calling hours the call is scheduled, not dialled — the response says when.
POST/api/v1/calls
Place (or schedule) an outbound call.
{
"agent_id": "…",
"to": "+41441234567",
"contact": { "name": "Anna Keller", "kind": "b2c" },
"goal": "Confirm Tuesday's appointment",
"language": "de",
"consent": { "basis": "existing_customer" },
"external_ref": "crm-8812",
"callback_url": "https://example.com/hooks/calls"
}{ "call_id": "…", "status": "dialing" }
// or, outside local hours:
{ "call_id": "…", "status": "scheduled", "scheduled_for": "2026-10-01T07:00:00Z" }
// or, blocked by the gate (HTTP 422):
{ "call_id": "…", "status": "canceled", "reason": "consent_required" }GET/api/v1/calls
List calls, newest first (filter by agent_id, status, direction).
GET/api/v1/calls/{id}
A call with its transcript, outcome, actions, latency and cost.
{
"id": "…", "direction": "outbound", "status": "completed", "outcome": "booked",
"duration_seconds": 143, "cost_credits": 406,
"transcript": [{ "direction": "out", "text": "Just so you know, I'm Alex, an AI assistant…" }],
"actions": [{ "type": "book_appointment", "starts_at": "2026-10-06T12:30:00Z" }],
"latency": { "turns": 11, "p50_ms": 760, "p95_ms": 1180 }
}POST/api/v1/calls/web
Start a browser test call; returns a LiveKit room and participant token.
{ "agent_id": "…" }{ "call_id": "…", "room": "web-…", "livekit_url": "wss://…", "token": "…" }Numbers
Buy a local number and route it to an agent. Some countries need an address or company document before a number activates (status needs_documents).
GET/api/v1/numbers
List numbers and the agent each routes to.
GET/api/v1/numbers/available?country=CH&type=local
Numbers you can buy now (type: local | mobile | toll_free; optional contains=digits).
POST/api/v1/numbers
Buy a number (a specific e164 from /available, or the first match) and optionally route it. 409 needs_documents when the country requires a regulatory bundle.
{ "country": "CH", "e164": "+41…", "type": "local", "agent_id": "…" }PATCH/api/v1/numbers/{id}
Route a number to another agent (or null to unassign).
{ "agent_id": "…" }DELETE/api/v1/numbers/{id}
Release a number: it stops ringing, goes back to the carrier and stops billing.
PATCH/api/v1/telephony
Suspend or reactivate every line in the workspace (owner/admin, dashboard session). Numbers stay yours while suspended.
{ "status": "suspended" }Calendar & bookings
The native calendar behind every booking tool. Linked Google or Microsoft calendars contribute their busy times.
GET/api/v1/availability?calendar_id={id}&from={iso}&days=7
Free slots on a calendar.
{ "slots": [{ "start": "2026-10-06T12:30:00Z", "end": "2026-10-06T13:00:00Z" }] }GET/api/v1/bookings
Bookings, newest first (filter by calendar_id, from, to).
Campaigns
An outbound agent over a contact list. The scheduler dials contacts inside their local window, retries per the campaign settings, and skips anyone the gate blocks.
POST/api/v1/campaigns
Create a campaign.
{ "agent_id": "…", "name": "October follow-ups", "goal": "Book a demo", "contact_ids": ["…"] }POST/api/v1/campaigns/{id}/start
Queue the campaign’s contacts for dialling.