Skip to main content

Agents

Agents are the core entity in VOCALS. Each agent defines a conversational AI persona with its own STT, LLM, and TTS provider configuration, system prompt, voice settings, and phone number assignments.

List Agents

GET /agents

Returns all agents for the current tenant, ordered by name.

Response

[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Support Agent",
"active_stt_provider_id": "...",
"active_llm_provider_id": "...",
"active_tts_provider_id": "...",
"is_active": true,
"phone_count": 2,
"has_webhook": true,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:00:00Z"
}
]

Response Fields (List)

FieldTypeDescription
iduuidAgent ID
namestringAgent display name
active_stt_provider_iduuid | nullAssigned STT provider
active_llm_provider_iduuid | nullAssigned LLM provider
active_tts_provider_iduuid | nullAssigned TTS provider
is_activebooleanWhether the agent is active
phone_countintegerNumber of assigned phone numbers
has_webhookbooleanWhether a webhook URL is configured
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp

Get Agent

GET /agents/{agent_id}

Returns full agent detail including phone number assignments.

Response

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Support Agent",
"active_stt_provider_id": "...",
"active_llm_provider_id": "...",
"active_tts_provider_id": "...",
"system_prompt": "You are a helpful support agent...",
"welcome_message": "Hello! How can I help you today?",
"voice_id": "rachel",
"language": "en",
"silence_threshold": 0.5,
"max_call_duration": 300,
"barge_in_sensitivity": "medium",
"stt_endpointing_sensitivity": "medium",
"interruptible": true,
"welcome_interruptible": false,
"amd_enabled": false,
"tts_config": { "speed": 1.0 },
"custom_variables": [
{ "name": "company_name", "default": "Acme Corp" },
{ "name": "support_hours", "default": "9am-5pm" }
],
"webhook_url": "https://example.com/webhook",
"webhook_secret": "whsec_...",
"is_active": true,
"phone_numbers": [
{
"id": "...",
"phone_number": "+15551234567",
"sip_config_id": "..."
}
],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:00:00Z"
}

Response Fields (Detail)

FieldTypeDescription
iduuidAgent ID
namestringAgent display name
active_stt_provider_iduuid | nullAssigned STT provider
active_llm_provider_iduuid | nullAssigned LLM provider
active_tts_provider_iduuid | nullAssigned TTS provider
system_promptstring | nullSystem prompt sent to the LLM
welcome_messagestring | nullMessage spoken at call start
voice_idstring | nullTTS voice identifier
languagestringLanguage code (e.g. en, es)
silence_thresholdfloatDeprecated and ignored. Stored and returned for backwards compatibility only; it has no effect on a call. Use stt_endpointing_sensitivity instead.
max_call_durationintegerMax call length in seconds (0 = unlimited)
barge_in_sensitivitystringvery_low, low, medium, high, or very_high
stt_endpointing_sensitivitystringvery_low, low, medium, high, or very_high. How quickly the agent decides the caller has finished speaking (see Response Trigger Speed).
interruptiblebooleanWhether the agent can be interrupted mid-speech
welcome_interruptiblebooleanWhether the welcome message can be interrupted
amd_enabledbooleanAnswering machine detection for outbound calls
tts_configobject | nullProvider-specific TTS settings
custom_variablesarray | nullPer-agent custom variable definitions, each { "name": ..., "default": ... }. Used to fill {{name}} placeholders in the system prompt and welcome message. See Dynamic Variables.
webhook_urlstring | nullURL for call event webhooks
webhook_secretstring | nullSecret for webhook signature verification
is_activebooleanWhether the agent is active
phone_numbersarrayAssigned phone numbers with SIP config references
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp

Create Agent

POST /agents

Request Body

{
"name": "Sales Agent",
"active_stt_provider_id": "uuid-of-stt-provider",
"active_llm_provider_id": "uuid-of-llm-provider",
"active_tts_provider_id": "uuid-of-tts-provider",
"system_prompt": "You are a sales representative...",
"welcome_message": "Hi there! Thanks for calling.",
"voice_id": "rachel",
"language": "en",
"max_call_duration": 600,
"barge_in_sensitivity": "medium",
"stt_endpointing_sensitivity": "medium",
"interruptible": true,
"welcome_interruptible": false,
"amd_enabled": false,
"tts_config": { "speed": 1.0 },
"custom_variables": [
{ "name": "company_name", "default": "Acme Corp" }
],
"webhook_url": "https://example.com/webhook",
"is_active": true,
"phone_numbers": [
{
"phone_number": "+15551234567",
"sip_config_id": "uuid-of-sip-config"
}
]
}

Request Fields

FieldTypeRequiredDefaultDescription
namestringYes--Agent display name
active_stt_provider_iduuidNonullSTT provider to use
active_llm_provider_iduuidNonullLLM provider to use
active_tts_provider_iduuidNonullTTS provider to use
system_promptstringNonullSystem prompt for the LLM
welcome_messagestringNonullMessage spoken when call starts
voice_idstringNonullTTS voice identifier
languagestringNo"en"Language code
silence_thresholdfloatNo0.5Deprecated and ignored. Still accepted so existing clients keep working, but it has no effect on a call. Use stt_endpointing_sensitivity instead.
max_call_durationintegerNo0Max call duration (0 = unlimited)
barge_in_sensitivitystringNo"medium"Barge-in sensitivity level
stt_endpointing_sensitivitystringNo"medium"How quickly the agent decides the caller has finished speaking (see Response Trigger Speed)
interruptiblebooleanNotrueAllow mid-speech interruption
welcome_interruptiblebooleanNofalseAllow welcome message interruption
amd_enabledbooleanNofalseEnable answering machine detection
tts_configobjectNonullExtra TTS provider config
custom_variablesarrayNonullPer-agent custom variable definitions (see below)
webhook_urlstringNonullWebhook endpoint URL
webhook_secretstringNonullWebhook signing secret
is_activebooleanNotrueWhether agent is active
phone_numbersarrayNonullPhone number assignments. Each phone_number must be E.164 with the country code (+34930485412); separators are stripped, and a value without a leading + and country code returns 422.

Custom Variables

custom_variables defines the agent's dynamic-variable placeholders. Each entry is an object with a name and a default:

"custom_variables": [
{ "name": "company_name", "default": "Acme Corp" },
{ "name": "support_hours", "default": "9am-5pm" }
]
FieldTypeDescription
namestringVariable name. Lowercase letters, digits, and underscores only. Must be unique within the agent and must not collide with a built-in variable name.
defaultstringRequired, non-empty default value used whenever the variable is not overridden for a call.

Reference a custom variable as {{name}} in the system_prompt or welcome_message; it is resolved at call start. Defaults can be overridden per call via the call-trigger API. For the full list of built-in variables and authoring behaviour, see Dynamic Variables.

The API returns 422 Unprocessable Entity when a default is empty or absent (the message names the offending variable), when a name is malformed, when names are duplicated, when a name collides with a built-in variable, or when the list exceeds the per-agent cap.

Response

201 Created -- Returns the full AgentResponse object.

Provider IDs are validated against your tenant's configured providers. If a provider ID is invalid or belongs to the wrong type (e.g. passing an LLM provider ID as the STT provider), the API returns 400 Bad Request.

tts_config is stored exactly as sent

No model is ever substituted for the one you configure. tts_config is persisted verbatim on both create and update: send no model_id and none is stored, in which case the call uses the model on the agent's TTS provider row.

An earlier release briefly seeded "model_id": "eleven_flash_v2_5" onto new ElevenLabs agents. That has been removed. Agents created while it was active still have the value in their stored tts_config and will keep using it until you send a different model_id or recreate them.

When the agent uses either Google TTS provider (google or google_gemini) together with a voice_id, the save runs a test synthesis of that exact voice before the agent is stored. If the synthesis fails - for example a voice the credential's project cannot reach, an invalid credential, or a Cloud Text-to-Speech key pasted into a google_gemini provider - the API returns 400 Bad Request with the underlying error surfaced, and the agent is not saved. If tts_config.google_style_prompt exceeds its maximum length of 500 characters, the API returns 422 Unprocessable Entity before any changes are made. Both checks apply to create and update.

tts_config.google_style_prompt

An optional delivery instruction, up to 500 characters, applied to every response the agent speaks:

{
"active_tts_provider_id": "550e8400-e29b-41d4-a716-446655440000",
"voice_id": "Zephyr",
"tts_config": { "google_style_prompt": "Speak warmly and slowly" }
}

It takes effect only when the agent's active TTS provider is google_gemini, whose voices accept delivery direction. Every other TTS provider ignores it - including google (Google Cloud TTS), which has no style capability on its surface: the value is stored but has no effect on synthesis. Note that google_gemini voice ids are bare prebuilt names such as Zephyr, not the locale-prefixed ids Google Cloud TTS uses.

Response Trigger Speed

stt_endpointing_sensitivity controls how quickly the agent decides the caller has finished speaking and starts replying. It uses the same five-level scale as barge_in_sensitivity, and defaults to "medium":

ValueBehaviour
very_lowWaits longest before replying. Best for callers who pause mid-sentence or read out long numbers.
lowWaits a little longer than the default.
mediumBalanced default.
highReplies sooner, at the cost of occasionally cutting in on a pause.
very_highFastest reply. Best for short, quick exchanges on a clean line.

Any other value returns 422 Unprocessable Entity listing the allowed values. The setting has no effect on speech-to-speech (live) agents, where the model handles end-of-speech detection itself.

Update Agent

PUT /agents/{agent_id}

Partial updates are supported. Only include the fields you want to change.

Request Body

{
"name": "Updated Agent Name",
"system_prompt": "New system prompt...",
"is_active": false
}

All fields from the create schema are accepted, but none are required.

Response

200 OK -- Returns the updated AgentResponse object.

Delete Agent

DELETE /agents/{agent_id}

Permanently deletes an agent and its phone number assignments.

Response

204 No Content -- No response body.

Get Agent by Phone Number

GET /agents/by-phone/{phone}

Look up the agent assigned to a specific phone number. Useful for routing logic.

Path Parameters

ParameterTypeDescription
phonestringPhone number in E.164 format (e.g. +15551234567)

Response

Returns the full AgentResponse object, or 404 if no agent is assigned to that number.