Agents
Create and manage voice agents over the API.
Everything the agent builder does is available here. The API manages the core, portable fields of an agent; console-only settings (such as call context) are preserved untouched when you update.
Every agent runs a flow. When you create an agent over the API, its systemPrompt is wrapped into a one-step flow, which is published straight away. Build multi-step flows in the console.
Agent shapes:
- List (
publicAgent):{ id, name, voice, language, status, channel, direction } - Detail / write (
publicAgentManaged): the list fields plussystemPrompt,workflowTemplate,vertical,policyRef,allowedTransferNumbers,extractionSchema,knowledgeBaseId,toolIds.
To place outbound calls, use an agent with status: "active", channel: "call", and direction: "outbound".
List agents
GET /v1/agents · scope agents:read
{ "data": [ { "id": "agt_…", "name": "Sales", "voice": "simran", "language": "hi", "status": "active", "channel": "call", "direction": "outbound" } ] }
Returns every agent in the workspace.
Get an agent
GET /v1/agents/:id · scope agents:read → { "data": publicAgentManaged }. Unknown id → 404 agent not found.
Create an agent
POST /v1/agents · scope agents:write
New agents are created as status: "draft" - publish before running them.
Body
| Field | Type | Required | Default / constraints |
|---|---|---|---|
name |
string | yes | 1–120 chars |
systemPrompt |
string | no | max 16000, default "" |
voice |
string | no | max 80, default "" |
language |
enum | no | en, hi, bn, gu, kn, ml, mr, or, pa, ta, te - default en |
workflowTemplate |
enum | no | collections, onboarding, prompt-driven - default prompt-driven |
vertical |
enum | no | general, collections, lending, financial_services, debt_recovery - default general |
policyRef |
string | no | compliance-pack ref (1–120), default generic-safe@1. Built-in (e.g. india-lending@1) or custom (cpk_…) |
toolIds |
string[] | no | catalog tool ids (each 1–64, max 50), default [] |
allowedTransferNumbers |
string[] | no | warm-transfer allowlist (each 1–20, max 50), default [] |
extractionSchema |
array | no | fields to capture: { key, label, type: "text"|"boolean"|"number" } (max 50), default [] |
knowledgeBaseId |
string | null | no | a knowledge base in your workspace, default null |
channel |
enum | no | call or chat - default call. Fixed once created. |
direction |
enum | no | outbound or inbound - default outbound (chat agents are always inbound). Fixed once created. |
Validation
- A regulated vertical (lending, financial services, debt recovery, collections) must be paired with a valid
workflowTemplateand a compliance pack that resolves, or you get a400/422. - A chat agent can’t use a regulated vertical (
400). allowedTransferNumbersandpolicyRefare validated. An unknownknowledgeBaseIdis400 knowledge_base_not_found.
Response - 201
{ "data": publicAgentManaged } with status: "draft".
Update an agent
PUT /v1/agents/:id · scope agents:write
A partial update: send only the fields you want to change - anything you leave out keeps its current value (same fields as create; channel and direction can’t change). Same validation as create. Unknown id → 404.
Changing systemPrompt updates the agent’s flow and republishes it, so the next call uses the new prompt. If the agent’s flow was built or edited in the console, a prompt change is refused with 409 agent_uses_flow - edit its steps with the flow endpoints instead. Other fields can still be changed.
Response 200: { "data": publicAgentManaged }.
Publish or unpublish
POST /v1/agents/:id/status · scope agents:write
{ "status": "active" } // publish; "draft" to unpublish
Publishing re-checks the vertical guard and compliance pack against the saved config (it can fail with the same guard errors). Response 200: { "data": publicAgentManaged }.
Voices and languages
GET /v1/voices · scope agents:read
The values an agent’s voice and language can take. Every voice speaks every language.
{
"data": {
"voices": [ { "id": "rohan", "name": "Rohan", "gender": "male" }, { "id": "priya", "name": "Priya", "gender": "female" }, … ],
"defaultVoice": "rohan",
"languages": [ { "code": "en", "label": "English (IN)" }, { "code": "hi", "label": "Hindi" }, … ]
}
}
Tools
GET /v1/tools · scope agents:read
The tools set up in your workspace: your webhooks, plus built-ins such as transfer to a person, end call and WhatsApp. Pass their ids as an agent’s toolIds. Tools are created and configured in the console.
{ "data": [ { "id": "tool_…", "type": "transfer_to_human", "name": null, "description": "" }, { "id": "tool_…", "type": "webhook", "name": "Look up order", "description": "…" } ] }
Call flow
An agent’s conversation is a flow: steps (nodes), each with its own prompt, joined by transitions (“when the caller agrees, go to Book”). The console’s builder edits the same flow these endpoints read and write. A flow has a draft, which you edit, and a published version, which live calls run.
Read the flow
GET /v1/agents/:id/flow · scope agents:read
{
"data": {
"draft": { "startNodeId": "n1", "nodes": [ … ], "variables": [ … ] },
"draftVersion": 7,
"published": { "startNodeId": "n1", "nodes": [ … ], "variables": [ … ] },
"issues": [ { "level": "warning", "code": "…", "message": "…", "nodeId": "n3" } ]
}
}
issues lists what’s wrong with the draft. error issues block publishing; warning issues don’t. The easiest way to learn the graph format is to read a flow built in the console.
Save the draft
PUT /v1/agents/:id/flow · scope agents:write
{ "graph": { "startNodeId": "n1", "nodes": [ … ], "variables": [ … ] }, "baseVersion": 7 }
Replaces the whole draft. A draft may be incomplete; you get its issues back along with the new draftVersion. Live calls are unaffected until you publish.
- Pass the
draftVersionyou read asbaseVersion. If someone changed the draft since then (in the console, the AI editor, or another client), you get409 flow_conflictand nothing is overwritten. Read it again and retry. - A step’s
transferNumbersmust be Indian+91numbers (400otherwise). - A body that isn’t a flow graph is
400.
Publish the draft
POST /v1/agents/:id/flow/publish · scope agents:write
Makes the draft the flow that live calls run. While the draft has errors (broken transitions, a missing end step, an integration it needs that isn’t connected, …), publishing is refused with 422 flow_not_ready and every issue:
{ "error": "the flow has errors - fix them and publish again", "code": "flow_not_ready", "issues": [ { "level": "error", "code": "dangling_target", … } ] }
The agent itself must also be published (above) to take calls.
Delete an agent
DELETE /v1/agents/:id · scope agents:write → { "data": { "id": "agt_…", "deleted": true } }.
409 agent_in_use- a campaign uses this agent. A campaign’s agent can’t be changed, so delete those campaigns first.404 agent not found
Next: Contacts →