VoxLink.ai

API Reference

Create assistant

Create a new AI assistant with specified configuration

Updated 30 June 2026

This endpoint allows you to create a new AI assistant with comprehensive configuration options.

Engine Modes

The API supports three engine modes, each with different capabilities:

Mode Description Required Fields
pipeline Traditional STT → LLM → TTS pipeline llm_model_id
multimodal Real-time multimodal AI multimodal_model_id
dualplex Multimodal brain + custom TTS voice multimodal_model_id

Request Body

Core Required Fields

namestringrequired

The name of the assistant (max 255 characters)

voice_idintegerrequired

The voice ID to use for the assistant. Use the Get Voices endpoint with the mode parameter to get compatible voices for your engine mode.

language_idintegerrequired

The language ID for the assistant. Use the Get Languages endpoint to get available languages.

typestringrequired

The assistant type. Options: inbound, outbound

modestringrequired

The engine mode. Options: pipeline, multimodal, dualplex

timezonestringrequired

The timezone for the assistant (e.g., "Europe/Bucharest", "America/New_York")

initial_messagestringrequired

The initial message the assistant will speak when the call starts (max 200 characters)

system_promptstringrequired

The system prompt that defines the assistant's behavior and personality

Mode-Specific Fields

llm_model_idinteger

The LLM model ID to use. Required for pipeline mode.

Use the Get Models endpoint to get available models.

multimodal_model_idinteger

The multimodal model ID. Required for multimodal and dualplex modes.

Use the Get Models endpoint to get available multimodal models.

chat_llm_fallback_idinteger

Fallback LLM model ID for tool calls in multimodal/dualplex modes. Optional.

turn_detection_thresholdnumber

Turn detection sensitivity for multimodal/dualplex modes (0-1). Default: auto

Secondary Languages

secondary_language_idsinteger[]

Array of additional language IDs the assistant can speak. The assistant will auto-detect and switch languages.

"secondary_language_ids": [2, 3, 4]

Knowledgebase Settings

knowledgebase_idinteger

The knowledgebase ID to attach to this assistant

knowledgebase_modestring

How to use the knowledgebase. Options:

  • function_call - AI calls a function to search (required for multimodal/dualplex)
  • prompt - Knowledge is injected into prompt (pipeline only)

Organization

folder_idinteger

ID of a folder to place this assistant in. Must belong to your account. Send null to leave the assistant uncategorized.

label_idsinteger[]

Array of label IDs to apply to this assistant. Each label must belong to your account.

"label_ids": [3, 5]

Phone Number

phone_number_idinteger

The ID of a phone number to assign to the assistant. Must belong to your account.

For `inbound` assistants, the phone number cannot be a Caller ID type and cannot be already assigned to another inbound assistant.

Custom Mid-Call Tools

tool_idsinteger[]

Array of custom mid-call tool IDs to attach. Each tool must belong to your account.

"tool_ids": [1, 5, 12]

Built-in Tools

toolsarray

Array of built-in tools to enable. Each tool has a type and tool-specific fields.

**call_transfer** - Transfer the call to another phone number
- `phone_number` (required): Phone number to transfer to (e.g., "+1234567890")
- `description`: When to transfer the call
- `custom`: If true, AI can determine transfer number dynamically
- `timezone`: Timezone for transfer availability
- `warm_transfer`: Send a message to the customer before transferring (default: `false`)
- `warm_transfer_message`: Prompt telling the AI what to say before transferring (e.g., "Tell the customer that the call is being transferred.")

**warm_call_transfer** - Warm transfer with supervisor briefing
- `supervisor_phone` (required): Phone number to dial for the warm transfer (e.g., "+14155552001"). If `custom_sip` is enabled, this is a SIP address or internal extension instead.
- `outbound_phone_id` (required): ID of the phone number used to dial the supervisor. Use [Get Phone Numbers](/api-reference/assistants/get-phone-numbers) to find available numbers.
- `description` (required): **When to transfer** — describes when the AI should initiate the warm transfer (e.g., "Transfer the call to a human supervisor when the customer requests to speak with a real person.")
- `custom_sip`: Enable to enter a custom SIP address or internal extension instead of a phone number (default: `false`)
- `caller_id_mode`: What phone number the supervisor sees when receiving the call. Options: `outbound_number` (default — shows the outbound phone number), `customer_number` (shows the caller's number), `custom` (shows a custom number)
- `custom_caller_id`: Custom phone number shown to supervisor. Only used when `caller_id_mode` is `custom`.
- `hold_music`: Audio played to the caller while on hold. Options: `hold_music` (default — plays default hold music), `none` (silence, no music)
- `hold_music_volume`: Volume level for hold music, 0-100 (default: `80`)
- `hold_message`: Message spoken to caller before placing them on hold (default: "Please hold while I connect you with a supervisor.")
- `summary_instructions`: Instructions for how the AI should brief the supervisor about the call (default: "Introduce the conversation from your perspective:\n- WHO is calling (name, company if mentioned)\n- WHY they called (their goal or problem)\n- WHY a human is needed at this point\n\nKeep it brief (2-3 sentences).")
- `briefing_initial_message`: The first message the AI says to the supervisor when they answer (default: "Hello! I have a caller on the line who needs your assistance. May I brief you on the situation?")
- `connected_message`: Message spoken to caller after supervisor is connected (default: "You are now connected with a supervisor. I'll leave you to it.")

**end_call** - End the call programmatically
- `description`: When the AI should end the call

**dtmf_input** - Send DTMF tones (keypad input)
- `description`: When to use DTMF input (for IVR navigation)

**collect_keypad** - Collect keypad input from the caller
- `timeout`: Seconds to wait for input, 1-30 (default: 5)
- `stop_key`: Key that ends input. Options: `#` (default), `*`

**calendar_integration** - Schedule appointments via Cal.com or Calendly
- `calendar_type`: Calendar provider. Options: `calcom` (default), `calendly`
- `description`: When to offer scheduling

Cal.com fields (`calendar_type: "calcom"`):
- `calcom_api_key` (required): Your Cal.com API key
- `calcom_event_slug` (required): The event type slug from Cal.com
- `calcom_team_slug`: Team slug if the event belongs to a Cal.com team
- `calcom_endpoint`: Cal.com API region. Options: `us` (default — `https://api.cal.com`), `eu` (`https://api.cal.eu`), `custom` (uses `calcom_custom_endpoint`)
- `calcom_custom_endpoint`: Custom Cal.com API base URL. Only used when `calcom_endpoint` is `custom` (e.g., `https://my-calcom-instance.com`).
- `calcom_event_id`: Cal.com event type ID. When provided, the event name is resolved from Cal.com automatically.
- `calcom_event_name`: Human-readable event name (e.g., `"30 Minute Meeting (30 min)"`). Resolved from Cal.com when `calcom_event_id` is provided, or set explicitly.
- `calcom_booking_fields`: Array of custom booking fields for the event. Each field has:
  - `slug` (required): Field identifier
  - `type` (required): Field type (e.g., "text", "email", "phone", "select")
  - `label` (required): Display label
  - `required`: Whether the field is required (default: `false`)
  - `options`: Array of options for select fields

Calendly fields (`calendar_type: "calendly"`):
- `calendly_api_key` (required): Your Calendly Personal Access Token (PAT). Generate one from your Calendly account: **Integrations & apps → API & webhooks → Generate new token**.
- `calendly_event_type_uri` (required): Full Calendly event type URI (e.g., `"https://api.calendly.com/event_types/{uuid}"`). Must belong to the authenticated PAT's account.

**assistant_transfer** - Hand off the conversation to a different AI assistant mid-call (swaps voice, LLM, and STT to the target assistant)
- `assistant_id` (required): ID of the target assistant. Must belong to your account.
- `description`: When to transfer (max 500 chars, default: "Transfer the conversation to this assistant when appropriate.")
- `message_before_transfer`: Optional message the AI speaks before switching to the target assistant (max 500 chars).
- `speak_transfer_greeting`: If `true`, the target assistant speaks its configured initial message after the transfer completes (default: `true`).
"tools": [
  {
    "type": "call_transfer",
    "phone_number": "+1234567890",
    "description": "Transfer when customer requests human support"
  },
  {
    "type": "warm_call_transfer",
    "supervisor_phone": "+1234567891",
    "outbound_phone_id": 7,
    "description": "Transfer the call to a human supervisor when the customer requests to speak with a real person.",
    "custom_sip": false,
    "caller_id_mode": "outbound_number",
    "hold_music": "hold_music",
    "hold_music_volume": 80,
    "hold_message": "Please hold while I connect you with a supervisor.",
    "summary_instructions": "Introduce the conversation from your perspective:\n- WHO is calling (name, company if mentioned)\n- WHY they called (their goal or problem)\n- WHY a human is needed at this point\n\nKeep it brief (2-3 sentences).",
    "briefing_initial_message": "Hello! I have a caller on the line who needs your assistance. May I brief you on the situation?",
    "connected_message": "You are now connected with a supervisor. I'll leave you to it."
  },
  {
    "type": "collect_keypad",
    "timeout": 5,
    "stop_key": "#"
  },
  {
    "type": "assistant_transfer",
    "assistant_id": 14765,
    "description": "Transfer to the Support Assistant when the customer needs technical help.",
    "message_before_transfer": "Sure — let me transfer you to our support specialist.",
    "speak_transfer_greeting": true
  },
  {
    "type": "end_call",
    "description": "End call when customer confirms satisfaction"
  }
]

Voice and TTS Settings

tts_emotion_enabledboolean

Whether to enable emotional text-to-speech synthesis

voice_stabilitynumber

Voice stability setting (0-1). Higher = more consistent voice

voice_similaritynumber

Voice similarity setting (0-1). Higher = closer to original voice

speech_speednumber

Speech speed multiplier (0.7-1.2)

llm_temperaturenumber

LLM temperature setting (0-1). Lower = more deterministic

synthesizer_provider_idinteger

Custom TTS provider ID. Auto-selected based on language if not provided. Use the Get Synthesizer Providers endpoint to discover available providers.

transcriber_provider_idinteger

Custom STT provider ID. Auto-selected based on language if not provided. Pipeline mode only. Use the Get Transcriber Providers endpoint to discover available providers.

Call Behavior Settings

allow_interruptionsboolean

Whether to allow caller interruptions.

Cannot be disabled for multimodal and dualplex modes.

fillersboolean

Whether to use filler audio during processing (e.g., "um", "let me check").

Only available for pipeline mode.

filler_configobject

Custom filler word profiles per category. If not provided, defaults are set based on the assistant's language. Each category is an array of short phrases.

  • positive: Filler words for positive/affirmative responses (e.g., "Great!", "Perfect!")
  • negative: Filler words for negative/neutral responses (e.g., "Hmm.", "Mhm.")
  • question: Filler words when processing a question (e.g., "Hmm.", "Let me think.")
  • neutral: Filler words for neutral acknowledgments (e.g., "Ok.", "I understand.")
"filler_config": {
  "positive": ["Super!", "Great!", "Perfect!"],
  "negative": ["Hmm.", "Mhm.", "I see."],
  "question": ["Hmm.", "Let me check.", "Good question."],
  "neutral": ["Ok.", "I understand.", "Noted."]
}

recordboolean

Whether to record the call

enable_noise_cancellationboolean

Whether to enable noise cancellation

wait_for_customerboolean

If true, the assistant waits for the customer to speak first

Timing Settings

max_durationinteger

Maximum call duration in seconds (20-1200)

max_silence_durationinteger

Maximum silence duration before re-engagement in seconds (1-360)

max_initial_silence_durationinteger

Maximum silence at call start before ending (1-120 seconds). Optional.

ringing_timeinteger

Maximum ringing time before giving up (1-60 seconds)

Re-engagement Settings

reengagement_intervalinteger

Re-engagement interval in seconds (7-600)

reengagement_promptstring

Custom prompt for re-engagement messages (max 1000 characters)

Example: "Are you still there? Do you have any other questions?"

Voicemail Settings

end_call_on_voicemailboolean

Whether to end call when voicemail is detected

voice_mail_messagestring

Message to leave on voicemail before hanging up (max 1000 characters)

Endpoint Detection

endpoint_typestring

Voice activity detection type. Options: vad, ai

endpoint_sensitivitynumber

Endpoint sensitivity level (0-5)

interrupt_sensitivitynumber

Interrupt sensitivity level (0-5)

min_interrupt_wordsinteger

Minimum words before interruption is allowed (0-10). Set to enable.

Ambient Sound

ambient_soundstring

Background ambient sound. Options: off, office, city, forest, crowded_room, cafe, nature

ambient_sound_volumenumber

Ambient sound volume level (0-1)

Webhook Configuration

is_webhook_activeboolean

Whether webhook notifications are enabled

webhook_urlstring

The webhook URL for post-call notifications. Required if is_webhook_active is true.

send_webhook_only_on_completedboolean

Whether to send webhooks only on completed calls (not failed/no-answer)

include_recording_in_webhookboolean

Whether to include recording URL in webhook payload

Post-Call Evaluation

post_call_evaluationboolean

Whether to enable AI post-call evaluation

post_call_schemaarray

Schema definition for post-call data extraction

namestringrequired

  Field name (3-16 chars, lowercase, alphanumeric and underscores only)

typestringrequired

  Data type. Options: `string`, `number`, `bool`

descriptionstringrequired

  Description of what this field represents (3-255 characters)
"post_call_schema": [
  {"name": "status", "type": "bool", "description": "Was the call objective achieved"},
  {"name": "summary", "type": "string", "description": "Brief summary of the call"}
]

Variables

variablesobject

Key-value pairs of custom variables accessible in prompts via {{variable_name}}

"variables": {
  "company_name": "Acme Corp",
  "product": "Premium Widget",
  "support_email": "support@acme.com"
}

Conversation Ended Settings

conversation_inactivity_timeoutinteger

Minutes of chat inactivity before the conversation is considered ended (1-1440)

conversation_ended_retriggerboolean

Whether to allow re-triggering the conversation after it ends due to inactivity

conversation_ended_webhook_urlstring

Webhook URL called when a chat conversation ends due to inactivity. Separate from the main call webhook.


Example Requests

Pipeline Mode Assistant

{
  "name": "Sales Assistant",
  "voice_id": 1,
  "language_id": 1,
  "type": "outbound",
  "mode": "pipeline",
  "timezone": "Europe/Bucharest",
  "initial_message": "Hello! How can I help you today?",
  "system_prompt": "You are a professional sales assistant...",
  "llm_model_id": 2,
  "secondary_language_ids": [2, 3],
  "knowledgebase_id": 1,
  "knowledgebase_mode": "prompt",
  "fillers": true,
  "filler_config": {
    "positive": ["Great!", "Perfect!", "Awesome!"],
    "negative": ["Hmm.", "I see."],
    "question": ["Good question.", "Let me check."],
    "neutral": ["Ok.", "Noted.", "I understand."]
  },
  "tool_ids": [1, 5],
  "tools": [
    {
      "type": "end_call",
      "description": "End call when customer is satisfied"
    },
    {
      "type": "call_transfer",
      "phone_number": "+1234567890",
      "description": "Transfer to support"
    },
    {
      "type": "warm_call_transfer",
      "supervisor_phone": "+1234567891",
      "outbound_phone_id": 7,
      "description": "Transfer the call to a human supervisor when the customer requests to speak with a real person.",
      "custom_sip": false,
      "caller_id_mode": "outbound_number",
      "hold_music": "hold_music",
      "hold_music_volume": 80,
      "hold_message": "Please hold while I connect you with a supervisor.",
      "summary_instructions": "Introduce the conversation from your perspective:\n- WHO is calling (name, company if mentioned)\n- WHY they called (their goal or problem)\n- WHY a human is needed at this point\n\nKeep it brief (2-3 sentences).",
      "briefing_initial_message": "Hello! I have a caller on the line who needs your assistance. May I brief you on the situation?",
      "connected_message": "You are now connected with a supervisor. I'll leave you to it."
    },
    {
      "type": "collect_keypad",
      "timeout": 5,
      "stop_key": "#"
    }
  ],
  "reengagement_interval": 20,
  "reengagement_prompt": "Are you still there?"
}

Multimodal Mode Assistant

{
  "name": "Support Bot",
  "voice_id": 41,
  "language_id": 1,
  "type": "inbound",
  "mode": "multimodal",
  "timezone": "America/New_York",
  "initial_message": "Hi! Welcome to support.",
  "system_prompt": "You are a helpful support agent...",
  "multimodal_model_id": 1,
  "chat_llm_fallback_id": 2,
  "turn_detection_threshold": 0.7,
  "knowledgebase_id": 1,
  "knowledgebase_mode": "function_call",
  "tts_emotion_enabled": false
}

Dualplex Mode Assistant

{
  "name": "Premium Agent",
  "voice_id": 1,
  "language_id": 2,
  "type": "outbound",
  "mode": "dualplex",
  "timezone": "Europe/Bucharest",
  "initial_message": "Buna ziua!",
  "system_prompt": "Esti un asistent profesionist...",
  "multimodal_model_id": 4,
  "chat_llm_fallback_id": 2,
  "secondary_language_ids": [1, 3],
  "knowledgebase_id": 1,
  "knowledgebase_mode": "function_call",
  "ambient_sound": "office",
  "ambient_sound_volume": 0.3
}

Response

messagestring

Success message confirming assistant creation

dataobject

idinteger

  The unique identifier of the created assistant

namestring

  The name of the assistant

statusstring

  The current status (`inactive` for new assistants)

typestring

  The type (`inbound` or `outbound`)

modestring

  The engine mode (`pipeline`, `multimodal`, or `dualplex`)
{
  "message": "Assistant created successfully",
  "data": {
    "id": 789,
    "name": "Sales Assistant",
    "status": "inactive",
    "type": "outbound",
    "mode": "pipeline"
  }
}
{
  "message": "Validation failed",
  "errors": {
    "name": ["The name field is required."],
    "voice_id": ["The selected voice is not compatible with the chosen engine type."],
    "knowledgebase_mode": ["Only function_call mode is available for multimodal assistants."]
  }
}

Notes

  • All required fields must be provided for successful assistant creation
  • Use the Get Voices endpoint with mode parameter to get compatible voices
  • For multimodal/dualplex modes, knowledgebase_mode must be function_call
  • For multimodal/dualplex modes, allow_interruptions is always enabled
  • Fillers are only available in pipeline mode
  • The assistant is created with inactive status by default

Related guides