Описания endpoints и полей показаны на английском языке, ровно так, как их публикует API. Это наш выбор: здесь вы читаете то же, что увидите в ответах.
GET /v1/agents#
List agents. Returns all agents on your account.
If your operator has configured guardrails, the expanded agent carries them read-only, and guardrails.input.action_by_channel says what the input guard's action means on each channel **for this agent**. It matters for one value: escalate is a real handover to a person only in a **chat** on an agent whose web_widget.enabled and web_widget.takeover.enabled are both on, because the handover runs through the same path the request-a-human tool uses and that path refuses when either switch is off. On a **voice** call it is refuse plus the fallback line and nothing more, since a phone leg has no takeover queue to enter. So one stored escalate reads back as {"voice": "refuse", "chat": "escalate"} on an agent with the widget handover armed and as {"voice": "refuse", "chat": "refuse"} on one without it - neither is a misconfiguration, they are the same setting reported honestly for the agent you asked about. The field is filled by the server on reads and ignored on writes.
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl "https://api.voiceland.ai/v1/agents" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"items": [
{
"deploy_state": "deployed",
"name": "front-desk"
}
]
}
POST /v1/agents#
Create or update an agent. Upserts an agent from the narrow tenant shape. Server-managed knobs (model, transcriber tuning, durations, tools) are filled from your account defaults; the response returns the fully expanded agent so you can see what was applied. Unknown fields are rejected with 422.
If your operator has configured guardrails, the expanded agent carries them read-only, and guardrails.input.action_by_channel says what the input guard's action means on each channel **for this agent**. It matters for one value: escalate is a real handover to a person only in a **chat** on an agent whose web_widget.enabled and web_widget.takeover.enabled are both on, because the handover runs through the same path the request-a-human tool uses and that path refuses when either switch is off. On a **voice** call it is refuse plus the fallback line and nothing more, since a phone leg has no takeover queue to enter. So one stored escalate reads back as {"voice": "refuse", "chat": "escalate"} on an agent with the widget handover armed and as {"voice": "refuse", "chat": "refuse"} on one without it - neither is a misconfiguration, they are the same setting reported honestly for the agent you asked about. The field is filled by the server on reads and ignored on writes.
Тело запроса
application/json Схема: Agent
| Поле |
Тип |
Обязательно |
Описание |
calendar_id |
string |
|
|
call_webhook |
CallWebhook |
|
Optional post-call POST: transcript + summary + extracted custom fields + audio URLs, delivered with retry + HMAC signing. |
cdr_export |
CDRExport |
|
Optional lean metadata-only post-call POST for billing / archive systems (no transcript or summary). |
data_sources |
array of string |
|
Ids of data sources (ds-…) whose latest snapshot is placed in the agent's context at call start. Up to 8. |
event_webhooks |
EventWebhooks |
|
Optional real-time per-event delivery (answered / caller utterance / agent utterance / hangup / transfer). |
identity |
Identity |
Да |
The agent's system prompt and first spoken line, your primary content surface. |
intents |
IntentTaxonomy |
|
|
knowledge_collections |
array of string |
|
|
language |
Language |
Да |
Primary BCP-47 language (drives speech recognition + the default summary language) plus optional secondary fallbacks. |
name |
string |
Да |
Logical identifier: lowercase, alphanumeric plus dash/underscore, ≤64 chars. |
notifications |
Notifications |
|
Optional per-call email recap to a list of recipients, independent of call_webhook. |
outbound |
boolean |
|
When true the agent is outbound-only (can be dialed via /calls/dial); when false (default) it is inbound-only and answers calls routed to its numbers. |
pickup_delay_s |
integer |
|
Seconds to wait after answering before the agent speaks its first line (0 to 15). Use 1 to 2 for a more human pace. |
re_engagement_prompt |
string |
|
Line spoken when the caller has been silent for the re-engagement interval. |
record_call |
boolean |
Да |
When true, per-call stereo + per-channel recordings are produced and their URLs exposed. |
search_widget |
SearchWidget |
|
Optional public knowledge-search box rendered by /search-widget.js on your site. Independent of web_widget: enabling the chat bubble never enables this, and this serves anonymous readers rather than a conversation. |
timezone |
string |
|
IANA timezone for any wall-clock formatting in prompts/tool args. Empty falls back to the account default. |
voice |
Voice |
Да |
The synthesized voice: provider + voice id (+ optional model). |
web_widget |
WebWidget |
|
Optional browser-embed voice/chat bubble rendered by /embed.js on your site. |
Ответы
| Код |
Описание |
200 |
The expanded agent. |
401 |
Missing or invalid API key. |
402 |
The agent uses a capability your plan does not include (feature_not_entitled, the message lists the feature codes), or the account has no subscription (no_subscription). |
409 |
Creating this agent would exceed your plan's agent allowance, one pool shared by voice and text agents, counted across your whole account (agent_limit, the message says how many the plan allows and how many exist), or this project's own agent limit. Updating an existing agent is never refused for this reason. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents" \
-H "Authorization: Bearer VL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"identity": {
"initial_message": "Acme Clinic, how can I help?",
"system_prompt": "You are the front desk of Acme Clinic. Help callers book appointments."
},
"language": {
"primary": "en-US"
},
"name": "front-desk",
"record_call": true,
"voice": {
"provider": "voiceland",
"voice_id": "pNInz6obpgDQGcFmaJgB"
}
}'
Пример ответа
{
"api_version": "2026-04-26",
"deploy_state": "draft",
"name": "front-desk"
}
POST /v1/agents/generate#
Generate an agent from a brief. Uses the language model to draft a complete agent from a free-text description, then upserts it. Returns the expanded agent.
Тело запроса
application/json Схема: AgentGenerateRequest
| Поле |
Тип |
Обязательно |
Описание |
description |
string |
Да |
Free-text description of what the agent should do. |
language |
string |
|
|
name |
string |
Да |
Name for the generated agent. |
pickup_delay_s |
integer |
|
|
record_call |
boolean |
|
|
timezone |
string |
|
|
voice_id |
string |
|
|
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents/generate" \
-H "Authorization: Bearer VL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "A friendly receptionist that greets callers and answers general questions about the business.",
"language": "en-US",
"name": "greeter",
"record_call": true
}'
Пример ответа
{
"deploy_state": "draft",
"name": "clinic-bot"
}
POST /v1/agents/wizard#
Draft an agent from structured input. Builds an agent from a small set of structured fields (industry, language, voice persona, transfer behavior). Non-persisting, returns the draft yaml + tenant agent for review.
Тело запроса
application/json
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents/wizard" \
-H "Authorization: Bearer VL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"industry": "receptionist",
"language": "en-US",
"name": "front-desk",
"voice": {
"gender": "female",
"style": "warm"
}
}'
Пример ответа
{
"name": "front-desk",
"warnings": [],
"yaml": "name: front-desk\n…"
}
DELETE /v1/agents/{name}#
Delete an agent. Permanently deletes the agent.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Ответы
| Код |
Описание |
204 |
Deleted. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X DELETE "https://api.voiceland.ai/v1/agents/{name}" \
-H "Authorization: Bearer VL_API_KEY"
GET /v1/agents/{name}#
Get an agent. Returns the fully expanded agent spec, including the server-filled defaults.
If your operator has configured guardrails, the expanded agent carries them read-only, and guardrails.input.action_by_channel says what the input guard's action means on each channel **for this agent**. It matters for one value: escalate is a real handover to a person only in a **chat** on an agent whose web_widget.enabled and web_widget.takeover.enabled are both on, because the handover runs through the same path the request-a-human tool uses and that path refuses when either switch is off. On a **voice** call it is refuse plus the fallback line and nothing more, since a phone leg has no takeover queue to enter. So one stored escalate reads back as {"voice": "refuse", "chat": "escalate"} on an agent with the widget handover armed and as {"voice": "refuse", "chat": "refuse"} on one without it - neither is a misconfiguration, they are the same setting reported honestly for the agent you asked about. The field is filled by the server on reads and ignored on writes.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl "https://api.voiceland.ai/v1/agents/{name}" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"deploy_state": "deployed",
"name": "front-desk",
"spec": {
"guardrails": {
"input": {
"action": "escalate",
"action_by_channel": {
"chat": "escalate",
"voice": "refuse"
},
"enabled": true
}
}
}
}
POST /v1/agents/{name}/deploy#
Deploy an agent. Publishes the agent so it answers/originates live calls.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents/{name}/deploy" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"deploy_state": "deployed",
"name": "front-desk"
}
POST /v1/agents/{name}/rollback#
Roll back an agent. Restores a prior version as the current spec.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Тело запроса
application/json Схема: RollbackRequest
| Поле |
Тип |
Обязательно |
Описание |
version_id |
string |
Да |
The version to restore. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents/{name}/rollback" \
-H "Authorization: Bearer VL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"version_id": "v_…"
}'
Пример ответа
{
"deploy_state": "draft",
"name": "front-desk"
}
POST /v1/agents/{name}/test#
Start a test session. Mints a short-lived session so you can talk to the agent in the browser without a phone call. Returns a room + join token. A test session is a call: it spends one of your plan's simultaneous-call slots for as long as it runs.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
402 |
Too many simultaneous calls for your plan (concurrent_calls_cap): the message names how many your plan allows at once and how many are in progress, counted across your whole account. Nothing was placed or billed; retry when a call ends. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl -X POST "https://api.voiceland.ai/v1/agents/{name}/test" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"expires_at": "2026-07-15T12:00:00Z",
"room_name": "room_…",
"session_id": "sess_…"
}
GET /v1/agents/{name}/versions#
List agent versions. Every save snapshots the agent. Returns the version history.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl "https://api.voiceland.ai/v1/agents/{name}/versions" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"items": [
{
"created_at": "2026-07-14T09:00:00Z",
"version_id": "v_…"
}
]
}
GET /v1/agents/{name}/versions/{version_id}#
Get an agent version. Returns a specific snapshot including its full spec.
Параметры
| Имя |
Место |
Тип |
Обязательно |
Описание |
name |
path |
string |
Да |
Agent name. |
version_id |
path |
string |
Да |
Version id. |
Ответы
| Код |
Описание |
200 |
Success. |
401 |
Missing or invalid API key. |
4XX |
Request error (validation, not-found, etc.). |
5XX |
Server or upstream error. |
Пример запроса
curl "https://api.voiceland.ai/v1/agents/{name}/versions/{version_id}" \
-H "Authorization: Bearer VL_API_KEY"
Пример ответа
{
"spec": {
"name": "front-desk"
},
"version_id": "v_…"
}
Схемы#
Agent#
A voice agent. POST this shape to create or update an agent; server-managed knobs are filled from your account defaults.
| Поле |
Тип |
Обязательно |
Описание |
calendar_id |
string |
|
|
call_webhook |
CallWebhook |
|
Optional post-call POST: transcript + summary + extracted custom fields + audio URLs, delivered with retry + HMAC signing. |
cdr_export |
CDRExport |
|
Optional lean metadata-only post-call POST for billing / archive systems (no transcript or summary). |
data_sources |
array of string |
|
Ids of data sources (ds-…) whose latest snapshot is placed in the agent's context at call start. Up to 8. |
event_webhooks |
EventWebhooks |
|
Optional real-time per-event delivery (answered / caller utterance / agent utterance / hangup / transfer). |
identity |
Identity |
Да |
The agent's system prompt and first spoken line, your primary content surface. |
intents |
IntentTaxonomy |
|
|
knowledge_collections |
array of string |
|
|
language |
Language |
Да |
Primary BCP-47 language (drives speech recognition + the default summary language) plus optional secondary fallbacks. |
name |
string |
Да |
Logical identifier: lowercase, alphanumeric plus dash/underscore, ≤64 chars. |
notifications |
Notifications |
|
Optional per-call email recap to a list of recipients, independent of call_webhook. |
outbound |
boolean |
|
When true the agent is outbound-only (can be dialed via /calls/dial); when false (default) it is inbound-only and answers calls routed to its numbers. |
pickup_delay_s |
integer |
|
Seconds to wait after answering before the agent speaks its first line (0 to 15). Use 1 to 2 for a more human pace. |
re_engagement_prompt |
string |
|
Line spoken when the caller has been silent for the re-engagement interval. |
record_call |
boolean |
Да |
When true, per-call stereo + per-channel recordings are produced and their URLs exposed. |
search_widget |
SearchWidget |
|
Optional public knowledge-search box rendered by /search-widget.js on your site. Independent of web_widget: enabling the chat bubble never enables this, and this serves anonymous readers rather than a conversation. |
timezone |
string |
|
IANA timezone for any wall-clock formatting in prompts/tool args. Empty falls back to the account default. |
voice |
Voice |
Да |
The synthesized voice: provider + voice id (+ optional model). |
web_widget |
WebWidget |
|
Optional browser-embed voice/chat bubble rendered by /embed.js on your site. |
AgentGenerateRequest#
| Поле |
Тип |
Обязательно |
Описание |
description |
string |
Да |
Free-text description of what the agent should do. |
language |
string |
|
|
name |
string |
Да |
Name for the generated agent. |
pickup_delay_s |
integer |
|
|
record_call |
boolean |
|
|
timezone |
string |
|
|
voice_id |
string |
|
|
CDRExport#
| Поле |
Тип |
Обязательно |
Описание |
headers |
map of string |
|
|
method |
string |
|
|
url |
string |
Да |
HTTPS endpoint the lean metadata-only CDR payload is delivered to. |
CallWebhook#
| Поле |
Тип |
Обязательно |
Описание |
custom_fields |
array of CustomField |
|
Fields the model extracts from the transcript and includes in the payload. |
headers |
map of string |
|
Extra request headers sent verbatim (e.g. an Authorization bearer the receiver expects). |
method |
string |
|
HTTP method, POST (default), PUT, or PATCH. |
summary_languages |
array of string |
|
One post-call summary per BCP-47 code; empty uses the agent's primary language. |
url |
string |
Да |
HTTPS endpoint the post-call payload is delivered to. |
CustomField#
| Поле |
Тип |
Обязательно |
Описание |
name |
string |
Да |
Key under which the extracted value is delivered. |
prompt |
string |
Да |
One-line instruction telling the model what to extract; return null when undeterminable. |
type |
string |
|
Informational type hint (e.g. string). |
EmailNotification#
| Поле |
Тип |
Обязательно |
Описание |
custom_fields |
array of CustomField |
|
|
summary_languages |
array of string |
|
|
to |
array of string |
Да |
|
Error#
Error envelope returned for non-2xx responses.
| Поле |
Тип |
Обязательно |
Описание |
error |
object |
Да |
|
EventWebhook#
| Поле |
Тип |
Обязательно |
Описание |
enabled |
boolean |
Да |
|
headers |
map of string |
|
|
method |
string |
|
|
url |
string |
Да |
|
EventWebhooks#
Identity#
The agent's system prompt and opening line.
| Поле |
Тип |
Обязательно |
Описание |
initial_message |
string |
Да |
The exact first line the agent speaks on pickup (spoken verbatim, not model-generated). |
system_prompt |
string |
Да |
The master instruction set the model follows for the whole call. |
Intent#
| Поле |
Тип |
Обязательно |
Описание |
action |
string |
Да |
|
description |
string |
|
|
examples |
array of string |
|
|
name |
string |
Да |
|
target |
string |
|
|
IntentTaxonomy#
| Поле |
Тип |
Обязательно |
Описание |
enabled |
boolean |
Да |
|
items |
array of Intent |
|
|
threshold |
number |
|
|
unknown_action |
string |
|
|
Language#
| Поле |
Тип |
Обязательно |
Описание |
primary |
string |
Да |
Primary language as a BCP-47 tag, e.g. el-GR or en-US. |
secondary |
array of string |
|
Additional BCP-47 languages the agent may switch to. |
Notifications#
RollbackRequest#
| Поле |
Тип |
Обязательно |
Описание |
version_id |
string |
Да |
The version to restore. |
Public knowledge-search box for your own site. It serves anonymous visitors, so it is switched on separately from the chat bubble and must name both the sites that may embed it and the collections it may search.
| Поле |
Тип |
Обязательно |
Описание |
allowed_origins |
array of string |
|
Exact-match list of page origins that may query this widget ("https://example.com", scheme, host, optional port; no path, no wildcard). REQUIRED when enabled. Exact match only, so serving both the apex and www means listing both. |
collections |
array of string |
|
Knowledge-base collection ids this widget may search. REQUIRED when enabled, unlike elsewhere in the API an empty list does not mean "everything published", because for an anonymous reader that default would publish your whole corpus. |
enabled |
boolean |
Да |
Master switch. While false the public endpoints report the widget as unavailable and answer nothing. |
lang |
string |
|
Default BCP-47 language of the page the widget sits on, used as the retrieval preference when a query does not state one. Empty means no preference. |
no_results_text |
string |
|
Line shown when a search matches nothing. |
placeholder |
string |
|
Placeholder text inside the input. |
primary_color |
string |
|
Accent colour as a hex literal (e.g. #3B82F6). |
result_limit |
integer |
|
Results per query. 0 uses the service default; the service caps the ceiling regardless. |
title |
string |
|
Heading rendered above the search box. |
TransferWebhook#
| Поле |
Тип |
Обязательно |
Описание |
custom_fields |
array of CustomField |
|
|
enabled |
boolean |
Да |
|
headers |
map of string |
|
|
method |
string |
|
|
url |
string |
Да |
|
Voice#
| Поле |
Тип |
Обязательно |
Описание |
model |
string |
|
Optional voice model/engine override; empty uses the provider default. |
provider |
string |
Да |
Voice provider identifier. |
voice_id |
string |
Да |
The voice to use. |
| Поле |
Тип |
Обязательно |
Описание |
ai_responses_enabled |
boolean |
|
|
allowed_origins |
array of string |
|
|
auto_open |
boolean |
|
|
automation_webhook_url |
string |
|
|
avatar_url |
string |
|
|
busy_text |
string |
|
|
button_main_text |
string |
|
|
button_size |
string |
|
|
button_style |
string |
|
|
button_sub_text |
string |
|
|
chat_enabled |
boolean |
Да |
|
chat_placeholder |
string |
|
|
chat_tab_label |
string |
|
|
default_mode |
string |
|
|
enabled |
boolean |
Да |
|
end_confirm_no_text |
string |
|
|
end_confirm_text |
string |
|
|
end_confirm_yes_text |
string |
|
|
header_subtitle |
string |
|
|
header_title |
string |
|
|
layout |
string |
|
|
modal_description |
string |
|
|
modal_title |
string |
|
|
position |
string |
|
|
pre_form |
WebWidgetPreForm |
|
|
primary_color |
string |
|
|
start_button_text |
string |
|
|
takeover |
WebWidgetTakeover |
|
|
voice_connecting_text |
string |
|
|
voice_disconnect_text |
string |
|
|
voice_enabled |
boolean |
Да |
|
voice_error_text |
string |
|
|
voice_tab_label |
string |
|
|
| Поле |
Тип |
Обязательно |
Описание |
key |
string |
Да |
|
label |
string |
Да |
|
required |
boolean |
|
|
type |
string |
|
|
| Поле |
Тип |
Обязательно |
Описание |
description |
string |
|
|
fields |
array of WebWidgetFormField |
|
|
submit_text |
string |
|
|
title |
string |
|
|
| Поле |
Тип |
Обязательно |
Описание |
closed_message |
string |
|
|
enabled |
boolean |
Да |
|
no_rep_message |
string |
|
|