> ## Documentation Index
> Fetch the complete documentation index at: https://docs.topcalls.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a new call

> Create and dispatch an AI-powered phone call. The call will be queued and executed immediately.

**Phone Number Format**: Must be in E.164 format (e.g., `+14155551234`)
- Must start with `+`
- Country code must be 1-9 (not 0)
- Total length: 1-15 digits after the `+`

**Simple Mode**: Provide `task` (simple prompt)
**Advanced Mode**: Provide `instructions` (full system prompt)




## OpenAPI

````yaml /api-reference/openapi.json post /v1/calls
openapi: 3.0.3
info:
  title: TopCalls Voice API
  description: >
    TopCalls Voice Gateway API for creating and managing AI-powered phone calls.


    ## Authentication


    All API requests require authentication. Include your API key in the
    `Authorization` header:


    ```

    Authorization: Bearer tc_live_xxxxx

    ```


    ## Rate Limits


    Direct call creation via `POST /v1/calls` is limited to your account's

    `max_calls_per_minute` setting (default: 20) per minute. Exceeding it
    returns

    `429 Too Many Requests` with a `Retry-After` header.

    All endpoints are additionally subject to a flat limit of 120 requests per

    minute per account (all methods).


    On a `429`, wait for the number of seconds in the `Retry-After` header, then

    retry the same request. For automated clients, back off progressively on

    repeated `429`s. Limits are per account and are shared by all API keys.


    ## Error Format


    All errors follow RFC 7807 Problem+JSON format:


    ```json

    {
      "type": "https://api.topcalls.ai/errors/insufficient_quota",
      "title": "Insufficient Quota",
      "status": 402,
      "detail": "You need 5 minutes but have 3.5 remaining"
    }

    ```
  version: 1.0.0
  contact:
    name: TopCalls Support
    url: https://topcalls.ai
  license:
    name: Proprietary
servers:
  - url: https://api.topcalls.ai
    description: Production
security: []
tags:
  - name: Calls
    description: Create and manage phone calls
  - name: Phone Numbers
    description: Manage phone numbers and carriers
  - name: Account
    description: Account information and usage
  - name: Webhooks
    description: Webhook configuration and events
  - name: Configuration
    description: Available AI models, voices, and platform capabilities
paths:
  /v1/calls:
    post:
      tags:
        - Calls
      summary: Create a new call
      description: >
        Create and dispatch an AI-powered phone call. The call will be queued
        and executed immediately.


        **Phone Number Format**: Must be in E.164 format (e.g., `+14155551234`)

        - Must start with `+`

        - Country code must be 1-9 (not 0)

        - Total length: 1-15 digits after the `+`


        **Simple Mode**: Provide `task` (simple prompt)

        **Advanced Mode**: Provide `instructions` (full system prompt)
      operationId: createCall
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCallRequest'
            examples:
              simple:
                summary: Simple call
                value:
                  phone_number: '+14155551234'
                  task: Call to confirm John's appointment tomorrow at 3 PM
              realtime:
                summary: Realtime mode (default)
                value:
                  phone_number: '+14155551234'
                  from_number: '+18005551234'
                  instructions: You are Rachel, a friendly appointment coordinator...
                  first_sentence: Hi, this is Rachel from TopView Dental...
                  voice: alloy
                  model: gpt-realtime-2
                  mode: realtime
                  temperature: 0.7
                  max_duration: 10
                  webhook_url: https://your-app.com/webhooks/call-complete
                  metadata:
                    patient_id: pat_123
              legacy_custom_tts:
                summary: Legacy mode with custom TTS
                value:
                  phone_number: '+14155551234'
                  from_number: '+18005551234'
                  instructions: You are Rachel, a friendly appointment coordinator...
                  first_sentence: Hi, this is Rachel from TopView Dental...
                  voice: rachel
                  mode: legacy
                  stt_provider: deepgram
                  stt_model: nova-3
                  stt_language: en-US
                  tts_provider: elevenlabs
                  tts_model: eleven_flash_v2_5
                  tts_stability: 0.75
                  tts_similarity_boost: 0.5
                  tts_speed: 0.78
                  temperature: 0.7
                  max_duration: 10
                  webhook_url: https://your-app.com/webhooks/call-complete
                  metadata:
                    patient_id: pat_123
              legacy_fast_tts:
                summary: Legacy mode with fast TTS
                value:
                  phone_number: '+14155551234'
                  from_number: '+18005551234'
                  instructions: You are Rachel, a friendly appointment coordinator...
                  first_sentence: Hi, this is Rachel from TopView Dental...
                  voice: aura-2-thalia-en
                  mode: legacy
                  stt_provider: deepgram
                  stt_model: nova-3
                  stt_language: en-GB
                  tts_provider: deepgram
                  temperature: 0.7
                  max_duration: 10
                  webhook_url: https://your-app.com/webhooks/call-complete
                  metadata:
                    patient_id: pat_123
              multilingual_detection:
                summary: Multi-language detection
                description: >
                  Uses restricted language detection.

                  By specifying exactly which languages to detect (English and
                  Romanian),

                  accuracy is dramatically improved compared to full
                  auto-detection.
                value:
                  phone_number: '+12025550123'
                  from_number: '+14155551234'
                  instructions: >-
                    You are a multilingual customer service agent. Respond in
                    the same language the customer uses.
                  first_sentence: Hello! How can I help you today?
                  voice: alloy
                  mode: legacy
                  stt_provider: gladia
                  stt_model: solaria-1
                  stt_languages:
                    - en
                    - ro
                  tts_provider: elevenlabs
                  tts_model: eleven_flash_v2_5
                  temperature: 0.7
                  max_duration: 10
                  webhook_url: https://your-app.com/webhooks/call-complete
              with_analysis:
                summary: Call with post-call analysis
                value:
                  phone_number: '+14155551234'
                  from_number: '+18005551234'
                  instructions: >-
                    You are Emma from Cabo Cribs Real Estate. Ask if they're
                    interested in Cabo properties...
                  first_sentence: Hi, this is Emma from Cabo Cribs Real Estate...
                  voice: maya
                  mode: legacy
                  max_duration: 10
                  webhook_url: https://your-app.com/webhooks/call-complete
                  analysis_schema:
                    converted:
                      type: boolean
                      description: >-
                        Whether the lead agreed to schedule an appointment or
                        expressed clear buying interest
                    questions:
                      type: string
                      description: >-
                        Questions the lead asked about properties, pricing, or
                        the buying process
                    objections:
                      type: string
                      description: Concerns or objections the lead raised during the call
                    call_outcome:
                      type: string
                      description: >-
                        Final outcome: appointment_scheduled,
                        callback_requested, not_interested, voicemail, or other
                    appointment_time:
                      type: date
                      description: >-
                        The scheduled appointment date and time if one was
                        booked
              with_transcript_correction:
                summary: Call with transcript correction vocabulary
                description: >
                  Uses transcript_correction_vocabulary to help the LLM correct
                  common STT mishearings.

                  The LLM uses context to interpret what the user likely meant,
                  without asking for clarification.
                value:
                  phone_number: '+14155551234'
                  from_number: '+18005551234'
                  instructions: >-
                    You are a technical support agent for CloudTech. Help users
                    troubleshoot their Kubernetes clusters and Weaviate
                    databases.
                  first_sentence: Hi, this is CloudTech support. How can I help you today?
                  voice: rachel
                  mode: legacy
                  stt_provider: deepgram
                  tts_provider: elevenlabs
                  max_duration: 15
                  transcript_correction_vocabulary:
                    - Kubernetes
                    - correct: Weaviate
                      sounds_like:
                        - we activate
                        - web VT
                        - weave E8
                    - correct: PostgreSQL
                      sounds_like:
                        - post grass
                        - postgres cool
                      context: database
                    - correct: NGINX
                      sounds_like:
                        - engine X
                        - N jinx
                      context: web server
                  webhook_url: https://your-app.com/webhooks/call-complete
              speechmatics_arabic_english:
                summary: Native Arabic+English code-switching
                description: >
                  Configuration for native Arabic and English code-switching.

                  The ar_en language code enables the provider's built-in
                  bilingual model,

                  which handles mid-sentence language switches without separate
                  detection steps.
                value:
                  phone_number: '+971501234567'
                  from_number: '+14155551234'
                  instructions: >-
                    You are a bilingual customer service agent. Respond in the
                    same language the customer uses, switching naturally between
                    Arabic and English.
                  first_sentence: مرحباً، كيف يمكنني مساعدتك اليوم؟
                  voice: rachel
                  mode: legacy
                  stt_provider: speechmatics
                  stt_language: ar_en
                  stt_max_delay: 1.5
                  tts_provider: elevenlabs
                  tts_model: eleven_flash_v2_5
                  max_duration: 15
                  webhook_url: https://your-app.com/webhooks/call-complete
              soniox_bilingual_code_switching:
                summary: English + Arabic code-switching
                description: >
                  Configuration for real-time bilingual transcription via the

                  stt_languages array (native code-switching).
                  stt_endpoint_sensitivity

                  is honoured in seconds (converted to the provider native
                  unit).
                value:
                  phone_number: '+971501234567'
                  from_number: '+14155551234'
                  instructions: >-
                    You are a bilingual customer service agent. Respond in the
                    same language the customer uses, switching naturally between
                    Arabic and English.
                  first_sentence: مرحباً، كيف يمكنني مساعدتك اليوم؟
                  voice: rachel
                  mode: legacy
                  stt_provider: soniox
                  stt_languages:
                    - en
                    - ar
                  stt_endpoint_sensitivity: 2
                  tts_provider: elevenlabs
                  tts_model: eleven_flash_v2_5
                  max_duration: 15
                  webhook_url: https://your-app.com/webhooks/call-complete
      responses:
        '201':
          description: Call created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateCallResponse'
              example:
                call_id: 564d4fd4-03bc-400a-abe0-05540fbeff88
                provider_call_id: 64e9bf0e-7c2f-4443-a759-7eb1731cd583
                status: queued
        '400':
          description: >-
            Invalid request (validation error, invalid phone number format,
            etc.)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                invalid_phone:
                  summary: Invalid phone number format
                  value:
                    status: 400
                    title: Invalid request body
                    errors:
                      - path: phone_number
                        message: >-
                          Phone number must be in E.164 format (e.g.,
                          +14155551234)
                        code: invalid_string
                missing_required:
                  summary: Missing required field
                  value:
                    status: 400
                    title: Invalid request body
                    errors:
                      - path: task
                        message: >-
                          Either task or instructions is required for direct
                          calls.
                        code: custom
        '401':
          description: Unauthorized (missing or invalid API key)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '402':
          description: Insufficient quota
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                status: 402
                title: Insufficient Quota
                detail: You need 5 minutes but have 3.5 remaining
        '403':
          description: Forbidden (missing required scope)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '409':
          $ref: '#/components/responses/IdempotencyConflict'
        '422':
          description: >
            Prompt safety verification failed — the call was **not** placed. The

            `task` / `instructions` / `first_sentence` / knowledge-base content

            (and any per-lead name/notes) is screened by an automated compliance

            review before dialing; non-compliant material is refused. No quota
            is

            reserved and no call is created. The `code` field identifies the
            reason:


            - `PROMPT_SAFETY_FRAUD` — the prompt was classified as fraudulent or
            deceptive

            - `PROMPT_SAFETY_LEAD_FRAUD` — per-lead free text (name/notes) was
            classified as fraudulent

            - `PROMPT_SAFETY_UNVERIFIABLE` — the review could not be completed;
            retry shortly

            - `PROMPT_SAFETY_RATE_LIMITED` — too many new prompts submitted for
            review; retry after a short wait


            Fix the prompt (or lead data) to describe a legitimate,
            clearly-identified

            campaign and retry. A prompt that has already passed review is
            cached and

            re-used, so repeated calls with the same content are not
            re-screened.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                status: 422
                title: Call Creation Failed
                detail: Failed to create call
                code: PROMPT_SAFETY_FRAUD
        '429':
          description: >
            Too many calls created too quickly. Direct call creation is limited
            to

            your account's `max_calls_per_minute` (default: 20) per minute. Wait
            the

            number of seconds given in the `Retry-After` response header, then
            retry.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
                example: 60
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                status: 429
                title: Too Many Requests
                detail: Failed to create call
                code: RATE_LIMITED
        '502':
          description: Provider error (telephony provider API error)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                status: 502
                title: Call Creation Failed
                detail: 'Call creation failed: HTTP 400'
                details: '{"msg":"invalid phone number format"}'
      security:
        - bearerAuth: []
components:
  parameters:
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        Optional client-supplied idempotency key. When present, the gateway
        caches the response for 24 hours and returns the same response on
        retried requests with the same key (account-scoped). Safe for
        retries on network blips. Format: 8-255 ASCII characters from
        `[A-Za-z0-9_-]`.
      schema:
        type: string
        minLength: 8
        maxLength: 255
        pattern: ^[A-Za-z0-9_-]+$
        example: a1b2c3d4-e5f6-7890-abcd-ef0123456789
  schemas:
    CreateCallRequest:
      type: object
      properties:
        phone_number:
          type: string
          pattern: ^\+[1-9]\d{1,14}$
          description: >
            Phone number in E.164 format (e.g., `+14155551234`)

            - Must start with `+`

            - Country code must be 1-9 (not 0)

            - Total length: 1-15 digits after the `+`

            - Also validated as dialable; country codes that don't exist are
            rejected
          example: '+14155551234'
        from_number:
          type: string
          pattern: ^\+[1-9]\d{1,14}$
          description: >
            Caller ID in E.164 format (optional, falls back to FROM_NUMBER env
            var)

            - Must be in E.164 format if provided

            - Either provide this or set FROM_NUMBER environment variable
          example: '+18005551234'
        first_sentence:
          type: string
          minLength: 1
          description: The AI's opening line
          example: >-
            Hi, this is Rachel from TopView Dental calling about your
            appointment.
        task:
          type: string
          minLength: 10
          description: |
            Simple prompt describing what the AI should do.
            Direct calls need at least one of `task` or `instructions` (both may
            be supplied). Not required for campaign execution (config comes from
            the campaign).
          example: Call to confirm John's appointment tomorrow at 3 PM
        instructions:
          type: string
          minLength: 10
          description: |
            Full system instructions for the AI.
            Direct calls need at least one of `task` or `instructions` (both may
            be supplied). Not required for campaign execution (config comes from
            the campaign).
          example: You are Rachel, a friendly appointment coordinator...
        mode:
          type: string
          enum:
            - realtime
            - legacy
          default: realtime
          description: >
            Conversation mode

            - `realtime`: Speech-to-speech mode (low latency)

            - `legacy`: Separate STT → LLM → TTS pipeline (custom voices, voice
            cloning)
        voice:
          type: string
          description: >
            Voice to use for AI responses.


            **Realtime mode:**

            - Available voices: `alloy`, `echo`, `shimmer`, `ash`, `ballad`,
            `coral`, `sage`, `verse`


            **Legacy mode (custom voices):**

            - Voice names: `rachel`, `domi`, `bella`, `antoni`, `elli`, `josh`,
            `arnold`, `sam`, `adam`, `nicole`, `matilda`

            - Or voice_id directly: `21m00Tcm4TlvDq8ikWAM` (24-char
            alphanumeric)

            - Custom/cloned voices: Use the voice_id from your account


            **Legacy mode (fast voices):**

            - Aura-2 voices: `aura-2-thalia-en`, `aura-2-orion-en`, etc.
          default: alloy
          example: alloy
        model:
          type: string
          description: >
            AI model to use for the call. Default is selected based on mode.


            See `GET /v1/models` for the complete list of available models and
            their capabilities.


            Defaults are automatically selected per mode if not specified.
        temperature:
          type: number
          minimum: 0
          maximum: 1
          default: 0.7
          description: >
            LLM creativity/temperature (0-1). Higher values = more creative
            responses.


            - Most models: Full range 0-1 supported

            - Some reasoning models only support default temperature
        stt_provider:
          type: string
          enum:
            - deepgram
            - gladia
            - speechmatics
            - soniox
          description: >
            STT provider (legacy mode only)

            - `deepgram`: Default provider (36+ languages)

            - `gladia`: Multi-language provider (100+ languages, automatic
            detection)

            - `speechmatics`: High-accuracy multilingual provider with native
            Arabic+English code-switching (use `stt_language: "ar_en"`)

            - `soniox`: Real-time multilingual provider with native
            code-switching via `stt_languages` array (e.g. `["en", "ar"]`)

            - Provider name must match telephony provider configuration

            - Use `stt_language: "multi"` for automatic multilingual detection
            (supported on select transcription engines)

            - Only used when `mode=legacy`
          default: deepgram
          example: deepgram
        stt_model:
          type: string
          minLength: 1
          description: >
            STT model (legacy mode only). See `GET /v1/models` for complete list
            of available STT models and their capabilities. Only used when
            `mode=legacy`.
          default: nova-3
          example: nova-3
        stt_language:
          type: string
          minLength: 2
          maxLength: 35
          description: >
            STT language code (legacy mode only). See `GET /v1/config` for the
            exact list per model.

            - With `stt_provider=deepgram`: accepts ISO 639-1 base codes plus
            supported regional variants (e.g. `en`, `en-US`, `en-GB`, `en-IN`,
            `zh-CN`, `pt-BR`)

            - With `stt_provider=gladia`: accepts only ISO 639-1 base codes
            (e.g. `en`, `ar`, `hi`). Regional variants are not supported - omit
            `stt_languages` (or send an empty array) for automatic multilingual
            detection

            - `multi` is a `stt_provider=deepgram`-only sentinel for
            multilingual code-switching (supported by `nova-3`, `nova-2`,
            `flux-general-multi`)

            - Only used when `mode=legacy`

            - For restricted multi-language detection with
            `stt_provider=gladia`, use the `stt_languages` array instead
          example: en-US
        stt_languages:
          type: array
          items:
            type: string
            minLength: 2
          minItems: 1
          maxItems: 10
          description: >
            Array of language codes for restricted multi-language detection
            (supported on select transcription engines).


            When multiple languages are provided:

            - Enables `code_switching` mode automatically

            - Restricts detection to ONLY these specified languages

            - Dramatically improves accuracy for short phrases


            Narrows the detection space from 99 languages to just the ones you
            specify.

            Omit this field (or send an empty array) for unrestricted
            multilingual auto-detection.


            Must be ISO 639-1 base codes only - regional variants like `en-US`
            or

            `zh-CN` are not accepted for restricted detection. See `GET
            /v1/config` for the full list.


            Examples:

            - `["en", "ro"]` - Detect English and Romanian only

            - `["en", "es", "fr"]` - Detect English, Spanish, and French

            - `["en", "ar", "hi"]` - Detect English, Arabic, and Hindi


            Only used when `mode=legacy` and `stt_provider=gladia`.
          example:
            - en
            - ro
        stt_vocabulary:
          type: array
          items:
            oneOf:
              - type: string
                minLength: 1
              - type: object
                required:
                  - value
                properties:
                  value:
                    type: string
                    minLength: 1
                    description: The word or phrase to boost
                  language:
                    type: string
                    minLength: 2
                    description: >-
                      ISO 639-1 language code for pronunciation (e.g., "en",
                      "ar")
          minItems: 1
          maxItems: 100
          description: |
            Custom vocabulary for STT (multi-language provider only).
            Boost recognition of domain-specific words and phrases in real time.

            **Formats supported:**
            - Simple strings: `["Capex", "TopCalls"]`
            - Objects with language: `[{"value": "Capex", "language": "en"}]`
            - Mixed: `["Capex", {"value": "مرحبا", "language": "ar"}]`

            **Use cases:**
            - Company/product names
            - Industry-specific terminology
            - Names that may be mispronounced
            - Technical terms

            Only used in legacy mode with the multi-language STT provider.
          example:
            - Capex
            - value: TopCalls
              language: en
        stt_endpoint_sensitivity:
          type: number
          minimum: 0.01
          maximum: 3
          description: >
            Endpoint delay: seconds to wait after the caller stops speaking
            before

            finalizing the turn. (The field is named `stt_endpoint_sensitivity`
            for

            backward compatibility, but it controls a wait time, not a
            sensitivity bias.)


            Effective range is provider-dependent:

            - `gladia`: 0.01 - 2.0 seconds (default 0.01; 0.01-0.1 recommended
            for telephony), maps to the provider's endpointing setting

            - `soniox`: 0.5 - 3.0 seconds (default 2.0), maps to the provider's
            max endpoint delay setting


            Lower values = snappier turn-ends; higher values = more patience for
            callers who pause mid-sentence.

            Values outside the active provider effective range may be clamped or
            rejected by the upstream provider.

            Only used in legacy mode and only honoured by providers that expose
            this knob.
          default: 0.01
          example: 0.01
        stt_endpoint_eagerness:
          type: number
          minimum: -1
          maximum: 1
          description: >
            Semantic endpoint-sensitivity bias (−1 to 1). Distinct from

            `stt_endpoint_sensitivity`, which is a delay in seconds: this is a

            unitless bias score that nudges the decision about whether the

            caller has finished a turn.


            - Negative values (e.g. −0.5): wait longer before ending the turn,
              reducing mid-sentence cut-offs on slow or thoughtful callers.
            - Positive values (e.g. 0.5): end turns more eagerly, snappier
              hand-off back to the agent.
            - Default: −0.3 (slightly more patient than the neutral 0).


            Only honoured when `stt_provider=soniox`. Ignored by other
            providers.
          default: -0.3
          example: -0.3
        stt_interrupt_sensitivity:
          type: number
          minimum: 0
          maximum: 1
          description: >
            STT interrupt/speech detection sensitivity (multi-language provider
            only).

            Controls the speech detection threshold for distinguishing speech
            from noise.


            - Range: 0.0 - 1.0

            - Default: 0.8 (recommended for telephony audio)

            - Higher values (0.7-0.9): Recommended for telephony audio,
            background noise

            - Lower values (0.0-0.4): More sensitive to speech, may pick up more
            noise


            Only used in legacy mode with the multi-language STT provider.
          default: 0.8
          example: 0.8
        stt_max_delay:
          type: number
          minimum: 0.7
          maximum: 4
          description: >
            Max wait in seconds before finalizing a transcript (supported on
            select transcription engines).

            Lower = snappier turn-ends, higher = more patience for slow
            speakers.


            - Range: 0.7 - 4.0 seconds

            - Default: 1.5 seconds

            - Fixed platform-wide for other providers.


            Only used in legacy mode with stt_provider=speechmatics.
          default: 1.5
          example: 1.5
        transcript_correction_vocabulary:
          type: array
          items:
            oneOf:
              - type: string
                minLength: 1
              - type: object
                required:
                  - correct
                properties:
                  correct:
                    type: string
                    minLength: 1
                    description: The correct term/word
                  sounds_like:
                    type: array
                    items:
                      type: string
                      minLength: 1
                    maxItems: 10
                    description: How STT might mishear this word (optional hints)
                  context:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Domain context for better correction (e.g., "medical",
                      "technology")
          minItems: 1
          maxItems: 100
          description: >
            Transcript correction vocabulary for LLM-based STT error correction
            (legacy mode only).

            Provides domain-specific terms that STT often mishears, allowing the
            LLM

            to use context to mentally correct transcription errors.


            **Formats supported:**

            - Simple strings: `["Weaviate", "Kubernetes", "TopCalls"]`

            - Objects with sounds_like hints:
              ```json
              [
                { "correct": "Weaviate", "sounds_like": ["we activate", "web VT"] },
                { "correct": "NVIDIA", "sounds_like": ["in video"], "context": "hardware" }
              ]
              ```
            - Mixed: `["TopCalls", { "correct": "Kubernetes", "sounds_like":
            ["cube net ease"] }]`


            **How it works:**

            - The vocabulary is added to the LLM system prompt

            - When STT mishears a domain term, the LLM uses context to interpret
            correctly

            - No additional latency (processed in the main LLM call)

            - LLM responds naturally without mentioning the correction


            **Use cases:**

            - Company/product names (Weaviate, Kubernetes, NVIDIA)

            - Industry-specific terminology (medical, legal, financial terms)

            - Technical terms that sound like common words

            - Names that may be mispronounced


            Only used when `mode=legacy`.
          example:
            - TopCalls
            - correct: Weaviate
              sounds_like:
                - we activate
                - web VT
            - correct: Kubernetes
              sounds_like:
                - cube net ease
                - cooper nettie
              context: technology
        tts_provider:
          type: string
          enum:
            - deepgram
            - elevenlabs
            - cartesia
          description: >
            TTS provider (legacy mode only). See `GET /v1/voices/builtin` for
            available voices per provider. Only used when `mode=legacy`.
          default: deepgram
          example: deepgram
        tts_model:
          type: string
          minLength: 1
          description: >
            TTS model (legacy mode only). See `GET /v1/models` for complete list
            of available TTS models. Only used when `mode=legacy`.
          example: eleven_flash_v2_5
        tts_stability:
          type: number
          minimum: 0
          maximum: 1
          description: |
            Voice stability (legacy mode).
            Controls the consistency of the voice output.
            - Lower values (0): More variable, emotional, expressive
            - Higher values (1): More consistent, stable, less expressive
            - Default: 0.75 (optimized for voice agents)
            - Only used in legacy mode with the corresponding TTS provider
          example: 0.75
        tts_similarity_boost:
          type: number
          minimum: 0
          maximum: 1
          description: |
            Voice similarity boost (legacy mode).
            Controls how closely the generated voice matches the original.
            - Lower values (0): Less similar to original voice
            - Higher values (1): More similar to original voice
            - Default: 0.5 (balanced for voice agents)
            - Only used in legacy mode with the corresponding TTS provider
          example: 0.5
        tts_speed:
          type: number
          minimum: 0.7
          maximum: 1.2
          description: |
            Speech speed (legacy mode).
            Controls the rate of speech.
            - Lower values (0.7): Slower speech
            - Higher values (1.2): Faster speech
            - Default: 0.78 (slightly slower for clarity)
            - Only used in legacy mode with the corresponding TTS provider
          example: 0.78
        tts_style:
          type: number
          minimum: 0
          maximum: 1
          description: >
            Style exaggeration (legacy mode).

            Controls expressiveness of the synthesized voice.

            - Lower values (0): Neutral, no style exaggeration

            - Higher values (1): Maximum expressiveness

            - Only effective on `eleven_multilingual_v2`; ignored by
            `eleven_flash_v2_5` and `eleven_turbo_v2_5`

            - When omitted, the TTS provider's own default applies

            - Only used in legacy mode with the corresponding TTS provider
          example: 0
        filler_enabled:
          type: boolean
          default: false
          description: >
            Enable filler acknowledgments (legacy mode only).

            When enabled, the AI will generate brief acknowledgments (e.g., "Got
            it...", "Sure...")

            before the main response to reduce perceived latency.


            - `false` (default): No filler - AI responds directly

            - `true`: AI generates contextual filler before main response


            Only used when `mode=legacy`.
          example: false
        emotion_enabled:
          type: boolean
          default: false
          description: |
            Enable expressive-speech markup (legacy mode, expressive-capable
            voices only). When enabled, the assistant may add inline prosody and
            native-language interjections to its spoken text for a more natural
            delivery.

            - `false` (default): plain delivery
            - `true`: expressive delivery

            Only used when `mode=legacy` and `tts_provider=cartesia` (the only
            provider that supports expressive markup). Has no effect otherwise.
          example: false
        block_interruption:
          type: boolean
          default: false
          description: >
            Block interruption mode (legacy mode only).

            When enabled, the AI continues speaking even if the user talks over
            it.


            - User speech during TTS is buffered (not processed immediately)

            - When TTS ends, buffered speech is merged and checked:
              - If ≥5 words: processed through LLM (single call)
              - If <5 words: discarded (fillers like "uh huh", "okay")

            Use cases:

            - Delivering critical information that shouldn't be interrupted

            - Users who provide active listening cues during AI speech

            - Noisy environments with background speech/noise


            Only used when `mode=legacy`.
          example: false
        bot_protection_enabled:
          type: boolean
          default: true
          description: |
            Enable bot and spam protection (legacy mode only).
            When enabled, the system detects automated or non-responsive
            callers and ends such calls automatically.

            - `true` (default): protection active
            - `false`: protection disabled for this call

            Only used when `mode=legacy`.
          example: true
        max_duration:
          type: number
          minimum: 1
          maximum: 60
          default: 5
          description: Maximum call duration in minutes (enforced by telephony provider)
        background_audio:
          type: string
          enum:
            - office
            - none
          default: office
          description: >
            Background audio preset to play during the call.

            - `office`: Office ambiance (default) - subtle office sounds

            - `none`: No background audio


            Background audio plays continuously under the conversation and helps
            create a professional atmosphere.
          example: office
        background_audio_gain:
          type: string
          enum:
            - low
            - medium
            - high
          default: medium
          description: |
            Volume level for background audio relative to speech.
            - `low`: Subtle (-10 dB) - quieter background
            - `medium`: Balanced (-4 dB) - noticeable but balanced (default)
            - `high`: Full volume (0 dB) - background at same level as speech

            Only used when `background_audio` is not `none`.
          example: medium
        webhook_url:
          type: string
          format: uri
          description: >
            Webhook URL to receive call completion/failure notifications.

            Webhook is sent after call finishes (includes recording_url and
            call_summary when available).
          example: https://your-app.com/webhooks/call-complete
        webhook_call_status_filter:
          type: array
          items:
            type: string
            minLength: 1
          maxItems: 20
          nullable: true
          description: >
            Restricts which call outcomes fire the `webhook_url` notification.


            - Omitted, `null`, or an empty array: every outcome fires the
            webhook (default).

            - Non-empty array: only calls whose final `call_status` matches a
            listed value
              fire the webhook (e.g. `["completed", "failed"]`).

            Only affects the per-call `webhook_url` delivery. Account-level
            webhook

            subscriptions are configured separately and are not filtered by this
            field.
          example:
            - completed
            - failed
        summary_prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: |
            Custom instruction for the post-call summary. When set, the summary
            included in the webhook payload and call record follows this
            instruction (e.g. "List the objections raised and the agreed
            callback time"). When omitted, the platform's default summary
            style applies.
          example: Summarize the objections raised and the agreed callback time.
        analysis_schema:
          type: object
          additionalProperties:
            oneOf:
              - type: string
                enum:
                  - boolean
                  - string
                  - text
                  - number
                  - date
              - type: object
                required:
                  - type
                  - description
                properties:
                  type:
                    type: string
                    enum:
                      - boolean
                      - string
                      - text
                      - number
                      - date
                  description:
                    type: string
                    minLength: 1
          description: >
            Schema for post-call AI analysis. Defines what information to
            extract from the transcript.

            After the call, AI analyzes the transcript and extracts structured
            data matching this schema.

            Results are included in the webhook payload under the `analysis`
            field.


            **Supported types:**

            - `boolean`: true/false values (e.g., "converted",
            "appointment_confirmed")

            - `string`/`text`: Free-form text (e.g., "objections", "questions")

            - `number`: Numeric values (e.g., "rating", "call_count")

            - `date`: Date/time in ISO 8601 format (e.g., "appointment_time")


            **Simple format:** Just specify the type

            ```json

            { "converted": "boolean", "objections": "string" }

            ```


            **Rich format:** Include description for better AI understanding

            ```json

            {
              "converted": {
                "type": "boolean",
                "description": "Whether the lead agreed to schedule an appointment"
              },
              "appointment_time": {
                "type": "date",
                "description": "The scheduled appointment date/time if booked"
              }
            }

            ```
          example:
            converted:
              type: boolean
              description: >-
                Whether the lead agreed to schedule an appointment or expressed
                buying interest
            objections:
              type: string
              description: Any concerns or objections the lead raised during the call
            appointment_time:
              type: date
              description: The scheduled appointment date and time if one was booked
        mcp_url:
          type: string
          format: uri
          description: |
            Optional MCP server URL for remote tool dispatch.
            When set, the gateway opens an SSE MCP client at call start and
            merges the remote tools into the LLM tool list.
          example: https://integrations.example.com/mcp/abc123
        mcp_tool_allowlist:
          type: array
          description: |
            Names of MCP tools (as returned by listTools()) that the AI is
            allowed to invoke during this call. When absent or empty, zero
            remote MCP tools are attached; only platform tools like end_call
            remain. Explicit opt-in to prevent prompt bloat from auto-attaching
            every flow in the connected workspace.
          items:
            type: string
          example:
            - book_callback
            - send_sms_confirmation
        tool_call_timeout_ms:
          type: integer
          minimum: 500
          maximum: 10000
          default: 3000
          description: |
            Per-call timeout for MCP tool invocation in milliseconds.
            On timeout, the gateway feeds {error: "tool_timeout"} into the
            second LLM hop so the model can recover conversationally.
        metadata:
          type: object
          additionalProperties: true
          description: >
            Custom metadata to include in webhook payload.

            System fields (task, voice, model, etc.) are filtered out
            automatically.
          example:
            patient_id: pat_123
            source: reminder_system
        lead_id:
          type: string
          format: uuid
          description: |
            Optional lead reference. When provided, the gateway loads the lead
            record (name, email, notes, status, plus any custom fields stored
            on the lead) and exposes them to the AI via lead_context.
            Caller-supplied lead_context takes precedence on key collision.
            Returns 404 if the lead does not exist in the calling account.
        campaign_id:
          type: string
          format: uuid
          description: |
            Optional campaign reference. When provided, the gateway loads
            the campaign's attached knowledge base and includes it in the
            call's runtime context. Returns 404 if the campaign does not
            exist in the calling account.

            When used as a campaign execution path (without `phone_number`),
            `campaign_id`, `lead_id`, `idempotency_key`, and `attempt_number`
            are all required.
        attempt_number:
          type: integer
          minimum: 1
          description: |
            Attempt number for campaign execution mode (required when
            `campaign_id` is provided without `phone_number`).
        idempotency_key:
          type: string
          minLength: 8
          description: |
            Idempotency key for campaign execution mode (required when
            `campaign_id` is provided without `phone_number`).
        scheduled_at:
          type: string
          format: date-time
          description: |
            Optional scheduled time for campaign execution mode.
        lead_context:
          type: object
          additionalProperties: true
          description: |
            Free-form key/value context surfaced to the AI during the call.
            When lead_id is set, the gateway auto-builds a base lead_context
            from the lead record; any keys passed here shallow-merge on top
            of the auto-built base and win on collision.
        crew:
          $ref: '#/components/schemas/CrewConfig'
      oneOf:
        - required:
            - phone_number
          anyOf:
            - required:
                - task
            - required:
                - instructions
        - required:
            - campaign_id
            - lead_id
            - idempotency_key
            - attempt_number
      additionalProperties: false
    CreateCallResponse:
      type: object
      properties:
        call_id:
          type: string
          format: uuid
          description: Call UUID
          example: 564d4fd4-03bc-400a-abe0-05540fbeff88
        provider_call_id:
          type: string
          nullable: true
          description: Provider call ID (may be null if call creation failed)
          example: 64e9bf0e-7c2f-4443-a759-7eb1731cd583
        status:
          type: string
          enum:
            - queued
            - pending
            - in_progress
            - completed
            - failed
            - cancelled
          description: Current call status
          example: queued
    Problem:
      type: object
      required:
        - status
        - title
      properties:
        type:
          type: string
          format: uri
          description: Error type URI
        title:
          type: string
          description: Error title
        status:
          type: integer
          description: HTTP status code
        detail:
          type: string
          description: Human-readable error detail
        code:
          type: string
          description: >
            Machine-readable error code for programmatic handling. Present on

            errors that carry a stable identifier (e.g. `PROMPT_SAFETY_FRAUD`,

            `job_not_found`, `too_many_ids`, `no_matches`). Distinct from the

            per-field `errors[].code` used for validation failures. Scenario-

            specific — see each endpoint's response examples for the exact
            value.
        instance:
          type: string
          format: uuid
          description: Request instance ID
        errors:
          type: array
          description: Validation errors (for 400 responses)
          items:
            type: object
            properties:
              path:
                type: string
                description: Field path (e.g., "phone_number", "metadata.from_number")
              message:
                type: string
                description: Error message
              code:
                type: string
                description: Error code (e.g., "invalid_string", "custom")
        details:
          type: string
          description: Additional error details (for provider errors)
    CrewConfig:
      type: object
      required:
        - members
      description: |
        Configuration for multiple specialised agents on a single call, with
        controlled handoffs between them. The first member answers the call;
        later members take over when their conditions are met. Availability
        is rolling out gradually.
      properties:
        members:
          type: array
          minItems: 2
          maxItems: 5
          description: 2-5 members. Unique ids. The first member is the entry member.
          items:
            $ref: '#/components/schemas/CrewMember'
        max_handoffs:
          type: integer
          minimum: 1
          maximum: 10
          default: 3
          description: Hard cap on handoffs per call.
    CrewMember:
      type: object
      required:
        - id
        - name
        - instructions
      properties:
        id:
          type: string
          minLength: 1
          description: Slug id, unique within the crew.
        name:
          type: string
          minLength: 1
          description: Display name (e.g. "Alex").
        instructions:
          type: string
          minLength: 1
          maxLength: 8000
          description: Member-specific instructions.
        use_knowledge_base:
          type: boolean
          description: When true, the knowledge base is appended to this member's prompt.
        knowledge_base_ids:
          type: array
          items:
            type: string
            format: uuid
          description: |
            Optional subset of this campaign's attached knowledge base entry ids
            visible to this member. When absent, `use_knowledge_base` controls
            all-or-none knowledge base access. An empty array gives this member
            no knowledge base entries.
        mcp_tool_allowlist:
          type: array
          items:
            type: string
            minLength: 1
          description: >
            Optional subset of the campaign-level `mcp_tool_allowlist` available

            to this member. When absent, the member inherits the campaign-level

            tool allowlist. An empty array gives this member no remote MCP
            tools.
        handoffs:
          type: array
          maxItems: 300
          description: Outbound handoff edges. Empty or absent means a terminal member.
          items:
            type: object
            required:
              - to
              - when
            properties:
              to:
                type: string
                minLength: 1
                description: >-
                  Destination member id. Must reference another member in the
                  same crew.
              when:
                type: string
                minLength: 1
                maxLength: 300
                description: >-
                  Free-form condition describing when to hand off to this
                  member.
  responses:
    IdempotencyConflict:
      description: |
        Another request with the same Idempotency-Key is currently being
        processed. Retry once it completes.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            status: 409
            title: 'Conflict: request in-flight'
            detail: >-
              Another request with the same Idempotency-Key is currently being
              processed.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        Use `Authorization: Bearer tc_live_xxxxx`

````