API reference
Agents
Create, read, update, delete and test voice agents.
An agent is a saved configuration: what the agent says first, which speech-to-text, language model and text-to-speech it uses, its prompts, its tools and where its webhooks go. Each create or update saves the configuration as a new version, and every call notes which version it used. The /v2/agent routes are the current ones; the /agent routes accept the older request shape and work on the same agents.
All routes need Authorization: Bearer <key>. Errors use the standard body {"error": <status>, "message": "..."} described in Errors. An unknown, deleted or foreign agent id always answers 404 with Agent not found.
| Operation | Method and path |
|---|---|
| Create an agent | POST /v2/agent |
| List agents | GET /v2/agent/all |
| Get an agent | GET /v2/agent/{agent_id} |
| Replace an agent | PUT /v2/agent/{agent_id} |
| Patch an agent | PATCH /v2/agent/{agent_id} |
| Delete an agent | DELETE /v2/agent/{agent_id} |
| Stop an agent's waiting calls | POST /v2/agent/{agent_id}/stop |
| Send a test webhook | POST /v2/agent/{agent_id}/webhook:test |
| Chat with an agent | POST /agent-chat/{agent_id} |
| Version 1 routes | POST /agent, GET /agent/all, GET /agent/{agent_id}, PUT /agent/{agent_id}, PATCH /agent/{agent_id} |
The agent configuration
A create or replace request has two top-level objects, both required.
| Field | Type | Description |
|---|---|---|
agent_config.agent_name | string | Display name. Required. |
agent_config.agent_type | string | Free-form category. Stored as other when omitted. |
agent_config.agent_welcome_message | string | The first thing the agent says. {name} and {{name}} placeholders are filled from the call's user_data. |
agent_config.tasks | array | The task list. The conversation task carries tools_config (llm_agent, synthesizer, transcriber, input, output, optional api_tools), toolchain and task_config. |
agent_config.webhook_url | string | Where execution payloads are posted on status changes. |
agent_config.webhook_statuses | array of strings | Statuses that send a webhook. Empty or absent means every status. |
agent_config.webhook_headers | object | Up to 20 custom headers sent with each webhook. Stored encrypted; reads return every value as **********. |
agent_config.calling_guardrails | object | call_start_hour and call_end_hour (0 to 23) and an optional timezone. Calls outside the window are rescheduled to the next start. |
agent_config.pre_call_webhook_url | string | A URL called before the call; it must pass the same URL checks as function tools. |
agent_config.call_summary_enabled | boolean | Write a summary after each call. |
agent_prompts | object | One entry per task, for example {"task_1": {"system_prompt": "..."}}. |
The body is checked against the agent schema first, and the first problem comes back as a 400 such as body: 'agent_prompts' is a required property. Further checks then apply to function tools, graph agents (Graph agents), ambient noise tracks (office-ambience, call-center, coffee-shop) and web search settings.
Note: If you send the webhook headers back with the masked value
**********, the stored value is kept. Whenwebhook_urlmoves to another host, stored headers are dropped unless you send the real values again.
Operations
Create an agent
POST /v2/agent
Creates an agent and its first version.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_config | body | object | yes | See The agent configuration. |
agent_prompts | body | object | yes | Prompts per task. |
Request
curl -X POST https://api.sevennadi.si/v2/agent \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{
"agent_config": {
"agent_name": "Renewal reminder",
"agent_welcome_message": "Hi {name}, this is Example Bank calling.",
"tasks": [{
"task_type": "conversation",
"tools_config": {
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {"provider": "openai", "model": "gpt-4o-mini"}
},
"synthesizer": {
"provider": "elevenlabs", "stream": true, "buffer_size": 250, "audio_format": "wav",
"provider_config": {"voice": "Nila", "voice_id": "V9LCAAi4tTlqe9JadbCo", "model": "eleven_turbo_v2_5"}
},
"transcriber": {"provider": "deepgram", "model": "nova-2", "language": "en", "stream": true},
"input": {"provider": "twilio", "format": "wav"},
"output": {"provider": "twilio", "format": "wav"}
},
"toolchain": {"execution": "parallel", "pipelines": [["transcriber", "llm", "synthesizer"]]},
"task_config": {"hangup_after_silence": 10, "call_terminate": 300}
}]
},
"agent_prompts": {"task_1": {"system_prompt": "You remind customers about policy renewals."}}
}'Response 201 Created
{
"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd",
"state": "created",
"version_id": "efd7ca74-9630-4f7f-a31d-427c231afc74"
}Errors
| Status | Message |
|---|---|
| 400 | The first schema problem, for example body: 'agent_prompts' is a required property |
| 400 | webhook_statuses must be a list of: scheduled, queued, rescheduled, initiated, ringing, in-progress, call-disconnected, completed, no-answer, busy, failed, canceled, stopped, error, balance-low |
| 400 | webhook_headers need a webhook_url |
| 400 | webhook_headers: at most 20 headers, webhook_headers: header '<name>' is reserved, webhook_headers: invalid header name '<name>' |
| 400 | Graph agent: <problem> |
| 400 | agent_config.tasks.<n>.task_config.ambient_noise_track must be one of: office-ambience, call-center, coffee-shop, or null |
List agents
GET /v2/agent/all
Returns every agent of the account that is not deleted, newest first. The list is not paginated.
Auth: API key or session token. Role: viewer and up.
No parameters.
Request
curl https://api.sevennadi.si/v2/agent/all \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
An array of agent objects, each in the shape shown under Get an agent.
Get an agent
GET /v2/agent/{agent_id}
Returns one agent with its current configuration and prompts.
Auth: API key or session token. Role: viewer and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
Request
curl https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{
"id": "f412f2b1-3493-4458-bcf2-8676cc798edd",
"agent_name": "Renewal reminder",
"agent_type": "other",
"agent_status": "processed",
"created_at": "2026-10-13T07:22:03Z",
"updated_at": "2026-10-13T07:22:03Z",
"tasks": [
{
"task_type": "conversation",
"toolchain": {"execution": "parallel", "pipelines": [["transcriber", "llm", "synthesizer"]]},
"task_config": {"call_terminate": 300, "hangup_after_silence": 10},
"tools_config": {
"input": {"format": "wav", "provider": "twilio"},
"output": {"format": "wav", "provider": "twilio"},
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {"model": "gpt-4o-mini", "provider": "openai"}
},
"synthesizer": {
"stream": true, "provider": "elevenlabs", "buffer_size": 250, "audio_format": "wav",
"provider_config": {"model": "eleven_turbo_v2_5", "voice": "Nila", "voice_id": "V9LCAAi4tTlqe9JadbCo"}
},
"transcriber": {"model": "nova-2", "stream": true, "language": "en", "provider": "deepgram"}
}
}
],
"call_summary_enabled": false,
"agent_prompts": {"task_1": {"system_prompt": "You remind customers about policy renewals."}},
"agent_welcome_message": "Hi {name}, this is Example Bank calling."
}webhook_url, webhook_statuses, calling_guardrails and ingest_source_config appear only when set. webhook_headers appears with masked values when headers are stored.
Errors
| Status | Message |
|---|---|
| 404 | Agent not found |
Replace an agent
PUT /v2/agent/{agent_id}
Replaces the whole configuration and prompts, and stores a new version. Send the complete body, as for create.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
agent_config | body | object | yes | The full configuration. |
agent_prompts | body | object | yes | The full prompts. |
Request
curl -X PUT https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d @agent.jsonResponse 200 OK
{"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd", "status": "updated"}Errors
The same 400 messages as Create an agent, plus 404 Agent not found.
Patch an agent
PATCH /v2/agent/{agent_id}
Changes part of an agent and stores a new version. Keys of agent_config overwrite the stored top-level keys. Two keys are handled specially: synthesizer replaces the synthesizer of the conversation task, and telephony_provider sets the input and output provider of every task and the matching audio format (wav for twilio and plivo, pcm for exotel, vobiz, sip and sip-trunk). Entries of agent_prompts are merged into the stored prompts per task.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
agent_config | body | object | no | Keys to change, for example agent_name, agent_welcome_message, webhook_url, webhook_statuses, webhook_headers, synthesizer, telephony_provider. |
agent_prompts | body | object | no | Prompts to merge, keyed by task. |
Request
curl -X PATCH https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"agent_config": {"agent_welcome_message": "Hello!", "telephony_provider": "exotel"}}'Response 200 OK
{"message": "success", "state": "updated"}Errors
| Status | Message |
|---|---|
| 400 | The first schema problem of the patch body |
| 400 | The webhook and configuration messages listed under Create an agent |
| 404 | Agent not found |
Delete an agent
DELETE /v2/agent/{agent_id}
Marks the agent deleted. It disappears from lists and can no longer be called. Its past executions stay readable.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
Request
curl -X DELETE https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{"message": "success", "state": "deleted"}Errors
| Status | Message |
|---|---|
| 404 | Agent not found |
Stop an agent's waiting calls
POST /v2/agent/{agent_id}/stop
Stops every call of the agent that has not started dialing: executions in scheduled, prepared, queued or rescheduled. Calls already in progress are not touched; stop those one by one with Stop a call.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
Request
curl -X POST https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd/stop \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{"stopped_executions": ["0b6c2c4e-7a55-4b0f-9a07-3d6b1f9f2a11"]}Errors
| Status | Message |
|---|---|
| 404 | Agent not found |
Send a test webhook
POST /v2/agent/{agent_id}/webhook:test
Posts a sample execution payload to the agent's webhook, so you can check your receiver before real calls. The sample is marked "is_test": true. You can test an unsaved URL and headers by sending them in the body. Saved header values are only sent to the host they were saved for. This route is not part of the core OpenAPI document.
Auth: API key or session token. Role: admin and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
webhook_url | body | string | no | URL to test instead of the saved one. |
webhook_headers | body | object | no | Headers to send instead of the saved ones. |
status | body | string | no | Status of the sample execution. Default completed. |
Request
curl -X POST "https://api.sevennadi.si/v2/agent/f412f2b1-3493-4458-bcf2-8676cc798edd/webhook:test" \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"status": "completed"}'Response 200 OK
{
"webhook_url": "https://hooks.example.test/calls",
"status": "completed",
"headers_sent": ["X-Token"],
"payload": {"id": "5a0f...", "agent_id": "f412f2b1-...", "status": "completed", "is_test": true},
"result": {"delivered": true, "http_status": 200, "response_body": "ok"}
}The call answers 200 even when delivery fails. Then result.delivered is false and result.error_type is http_error, unreachable or blocked.
Errors
| Status | Message |
|---|---|
| 400 | The agent has no webhook_url: save one or send webhook_url |
| 400 | status must be one of: scheduled, queued, rescheduled, ... |
| 400 | webhook_url is not allowed: <reason> |
| 403 | Your role (member) can't change webhooks. It needs admin access; ask an owner or admin of the workspace. |
| 404 | Agent not found |
Chat with an agent
POST /agent-chat/{agent_id}
Runs one text turn against the agent's saved configuration: its prompt, knowledge bases, function tools and, for a graph agent, its nodes. No call is placed and nothing is billed as a call. This route is not part of the core OpenAPI document.
The reply comes from the agent's language model when the account has credentials for it (an OpenAI-compatible provider key, a custom model, or the platform's local model). Without credentials the reply follows the deterministic rules of the mock engine, and provider is mock.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
messages | body | array | yes | 1 to 60 messages of {"role": "user" | "assistant", "content": "..."}. Each content is at most 4000 characters. The last one must be from the user. |
user_data | body | object | no | Values for prompt placeholders. |
state | body | object | no | Graph agents only: the state returned by the previous turn. |
mock_tool_calls | body | array | no | Scripts tool calls for the offline reply. |
Request
curl -X POST https://api.sevennadi.si/agent-chat/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "When is my renewal due?"}], "user_data": {"name": "Asha"}}'Response 200 OK
{
"reply": "Sure. (mock reply to: When is my renewal due?)",
"provider": "mock",
"model": null,
"passages": []
}tool_calls, transfer, state and ended are added when they apply.
Errors
| Status | Message |
|---|---|
| 400 | messages must be a non-empty list (at most 60) |
| 400 | each message needs role user|assistant and string content |
| 400 | messages are limited to 4000 characters |
| 400 | the last message must be from the user |
| 400 | user_data and state must be objects |
| 404 | Agent not found |
| 502 | The LLM provider failed: <detail> |
Version 1 routes
The version 1 routes work on the same agents and storage. They differ in two ways: create and replace validate the body against the older agent request schema, and responses never include ingest_source_config. Use the /v2/agent routes for new work. There is no version 1 delete; use Delete an agent.
Create an agent with version 1
POST /agent
Creates an agent from a version 1 request body (agent_config and agent_prompts).
Auth: API key or session token. Role: member and up.
Request
curl -X POST https://api.sevennadi.si/agent \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d @agent-v1.jsonResponse 200 OK
{"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd", "state": "created", "version_id": "efd7ca74-9630-4f7f-a31d-427c231afc74"}Note: This route answers
200, whilePOST /v2/agentanswers201.
Errors
400 with the first schema problem, and the configuration messages listed under Create an agent.
List agents with version 1
GET /agent/all
Returns every agent of the account, newest first.
Auth: API key or session token. Role: viewer and up.
Request
curl https://api.sevennadi.si/agent/all \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
An array of agent objects.
Get an agent with version 1
GET /agent/{agent_id}
Returns one agent.
Auth: API key or session token. Role: viewer and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
Request
curl https://api.sevennadi.si/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
The agent object, as in Get an agent.
Errors
404 Agent not found.
Replace an agent with version 1
PUT /agent/{agent_id}
Replaces the configuration and prompts from a version 1 request body and stores a new version.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | string (UUID) | yes | The agent. |
agent_config | body | object | yes | The full configuration. |
agent_prompts | body | object | yes | The full prompts. |
Request
curl -X PUT https://api.sevennadi.si/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d @agent-v1.jsonResponse 200 OK
{"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd", "status": "updated"}Errors
400 with the first schema problem; 404 Agent not found.
Patch an agent with version 1
PATCH /agent/{agent_id}
Behaves exactly like Patch an agent: same body, same response, same errors.
Auth: API key or session token. Role: member and up.
Request
curl -X PATCH https://api.sevennadi.si/agent/f412f2b1-3493-4458-bcf2-8676cc798edd \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"agent_config": {"agent_name": "Renewal reminder (Hindi)"}}'Response 200 OK
{"message": "success", "state": "updated"}