IllyVoIPdevelopers

Voice API

Gather DTMF or speech

Captures either keypad input or speech from the live call.

Try in API Playground ↗Sign in to prepare and run this request.
POST/api/v1/voice/call-control/gather

Before you start

Choose speech or DTMF, the prompt and supported language options for the active call.

Result

Read the captured value and any TTS/STT charges; a completed gather is different from a pending request.

Charges and safe retries

Use Idempotency-Key when speech or prompt TTS is billable. Do not change the key to bypass a pending outcome.

Authentication

Send your account API key in the X-Api-Key header. Keep it on your server; never embed it in browser code.

Request examples

Replace the example values with your own inputs. Examples do not run on this page. Production requests can change your account or incur charges.

cURL

cURL
curl -X POST "https://api.illyvoip.com/api/v1/voice/call-control/gather" \
  -H "X-Api-Key: ${ILLYVOIP_API_KEY:?Set ILLYVOIP_API_KEY}" \
  -H "Idempotency-Key: YOUR_UNIQUE_IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "call_control_id": "YOUR_CALL_CONTROL_ID",
    "input": "speech",
    "prompt_text": "Say your account number.",
    "voice": "illyvoip-emma",
    "prompt_language": "en-US",
    "speech_language": "en-US",
    "timeout_ms": 8000
}'

Node.js

Node.js
const response = await fetch("https://api.illyvoip.com/api/v1/voice/call-control/gather", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.ILLYVOIP_API_KEY,
    "Idempotency-Key": "YOUR_UNIQUE_IDEMPOTENCY_KEY",
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "call_control_id": "YOUR_CALL_CONTROL_ID",
    "input": "speech",
    "prompt_text": "Say your account number.",
    "voice": "illyvoip-emma",
    "prompt_language": "en-US",
    "speech_language": "en-US",
    "timeout_ms": 8000
})
});

const data = await response.json();
console.log(response.status, data);

PHP

PHP
<?php
$ch = curl_init('https://api.illyvoip.com/api/v1/voice/call-control/gather');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-Api-Key: ' . getenv('ILLYVOIP_API_KEY'),
        'Idempotency-Key: YOUR_UNIQUE_IDEMPOTENCY_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => '{
    "call_control_id": "YOUR_CALL_CONTROL_ID",
    "input": "speech",
    "prompt_text": "Say your account number.",
    "voice": "illyvoip-emma",
    "prompt_language": "en-US",
    "speech_language": "en-US",
    "timeout_ms": 8000
}',
]);

$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo $status . PHP_EOL;
echo $response;

Python

Python
import os
import json
import requests

response = requests.request(
    "POST",
    "https://api.illyvoip.com/api/v1/voice/call-control/gather",
    headers={
        "X-Api-Key": os.environ["ILLYVOIP_API_KEY"],
        "Idempotency-Key": "YOUR_UNIQUE_IDEMPOTENCY_KEY",
        'Content-Type': 'application/json'
    },
    json=json.loads("{\n    \"call_control_id\": \"YOUR_CALL_CONTROL_ID\",\n    \"input\": \"speech\",\n    \"prompt_text\": \"Say your account number.\",\n    \"voice\": \"illyvoip-emma\",\n    \"prompt_language\": \"en-US\",\n    \"speech_language\": \"en-US\",\n    \"timeout_ms\": 8000\n}"),
)

print(response.status_code)
print(response.json())

Node.js examples run on the server (Node.js 22.17+). Python examples require requests; PHP examples require cURL. Set the environment variables referenced in each example.

Request parameters

Header parameters

Idempotency-Keystringoptional

Required when prompt TTS or speech recognition is billable; otherwise optional. Reuse a key only for the same request.

minLength 8maxLength 128

Request body

application/json

Body required.

call_control_idstringrequired

Live control session ID.

nullable false
inputstringrequired

Accepted values: dtmf or speech.

prompt_textstringoptional

Text to synthesize, maximum 2,000 characters.

maxLength 2000
voicestringoptional

Optional voice name from List TTS voices with context=voice_api.

prompt_languagestringoptional

Optional TTS language for prompt_text. Use a canonical code from List TTS languages with context=voice_api, such as en-US.

speech_languagestringoptional

Optional STT language hint. Use a canonical code from the current STT options, such as en-US.

timeout_msintegeroptional
tts_enginestringoptional

Deprecated compatibility selector. Omit to use the current speech settings. Existing supported values remain accepted.

enginestringoptional

Deprecated compatibility selector. Omit to use the current speech settings. Existing supported values remain accepted.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "call_control_id": {
      "type": "string",
      "nullable": false,
      "description": "Live control session ID."
    },
    "input": {
      "type": "string",
      "description": "Accepted values: `dtmf` or `speech`."
    },
    "prompt_text": {
      "type": "string",
      "description": "Text to synthesize, maximum 2,000 characters.",
      "maxLength": 2000
    },
    "voice": {
      "type": "string",
      "description": "Optional voice name from `List TTS voices` with `context=voice_api`."
    },
    "prompt_language": {
      "type": "string",
      "description": "Optional TTS language for `prompt_text`. Use a canonical code from `List TTS languages` with `context=voice_api`, such as `en-US`."
    },
    "speech_language": {
      "type": "string",
      "description": "Optional STT language hint. Use a canonical code from the current STT options, such as `en-US`."
    },
    "timeout_ms": {
      "type": "integer"
    },
    "tts_engine": {
      "type": "string",
      "deprecated": true,
      "description": "Deprecated compatibility selector. Omit to use the current speech settings. Existing supported values remain accepted."
    },
    "engine": {
      "type": "string",
      "deprecated": true,
      "description": "Deprecated compatibility selector. Omit to use the current speech settings. Existing supported values remain accepted."
    }
  },
  "required": [
    "call_control_id",
    "input"
  ]
}
Example body
JSON
{
  "call_control_id": "vapi_760da5ee5a3c8b70777bae20fbda",
  "input": "speech",
  "prompt_text": "Say your account number.",
  "voice": "illyvoip-emma",
  "prompt_language": "en-US",
  "speech_language": "en-US",
  "timeout_ms": 8000
}

Request behavior

Use input: speech or input: dtmf to capture user input during the call. prompt_text is billed as TTS by character, and speech recognition is billed per started minute with stt_charge in the response. Idempotency-Key is required whenever prompt TTS or speech recognition is billable. It is optional when neither component is billable, but recommended for retries.

Charge transaction_id values match your ledger; unused components may be null or omitted. Reuse the same key while voice_request_pending is returned; voice_request_closed permits a new request. Omit speech_language for automatic recognition-language detection; # ends recorded speech.

Use an exact current voice ID from the Voice API catalog. Omitting voice uses the current default. Deprecated tts_engine/engine values remain accepted for compatibility and use the current speech settings.

Previously supported voice selections remain accepted and resolve to the corresponding current voice. Use the voice catalog for current identifiers. Unknown names and ambiguous voice_N ordinals are rejected.

Language hints remain separate from voice selection. A selected text prompt may return HTTP 403 with voice_content_review_required and fields.review_reference before charging, playback or input capture. Open Communication reviews in your account to explain the activity.

Repeating its key returns the same refusal; approval does not replay it. Selection order is prompt_media, then prompt_text, then prompt audio URL; unused text is not assessed.

Conditions and examples

Idempotency-Key is required for billable prompt TTS or speech recognition; it is optional when neither component is billable. Reuse a key only for the identical request. Prompt TTS uses the Voice API TTS catalog. Call List TTS languages with context=voice_api, then List TTS voices with the same context=voice_api for the prompt language. Current Voice API STT language options: en-US. Use prompt_language for prompt TTS and speech_language for recognition, or send just language when the same canonical code should be used for both.

Response fields

  • status: Request outcome. Read the resource state separately; success does not always mean delivery or completion.
  • call_control_id: Control session reference returned by Create or Answer; use it for subsequent live actions.
  • input: Input mode or captured input details for the gather operation.
  • transcript: Recognized speech text or transcript data.
  • tts_charge: Text-to-speech usage and charge, including a public ledger transaction reference when charged.
  • stt_charge: Speech-recognition usage and charge, including a public ledger transaction reference when charged.

HTTP responses

Expand a status to inspect its documented response format and examples. Example prices, IDs and timestamps are illustrative values, not quotes or account records.

200 Successful customer-facing response.

application/json

JSON
{
  "status": "success",
  "call_control_id": "vapi_760da5ee5a3c8b70777bae20fbda",
  "input": "speech",
  "transcript": "123456",
  "tts_charge": {
    "transaction_id": "TX-1A2B3C4D5E6F",
    "product": "voice_api_tts",
    "characters": 24,
    "rate_per_char_eur": 5e-05,
    "amount_eur": 0.0012
  },
  "stt_charge": {
    "transaction_id": "TX-2B3C4D5E6F70",
    "product": "voice_api_stt",
    "duration_seconds": 14,
    "billed_minutes": 1,
    "rate_per_min_eur": 0.02,
    "amount_eur": 0.02
  }
}
statusstringrequired
enum ["success"]
call_control_idstringrequired
nullable false
inputstringrequired
enum ["speech", "dtmf"]
transcriptstringoptional
tts_chargeobjectrequired
nullable true
View nested fields
transaction_idstringrequired

Public transaction reference matching your ledger, or null when no balance movement exists.

nullable truepattern "^TX-[A-F0-9]{12,24}$"
productstringrequired
charactersintegerrequired
rate_per_char_eurnumberrequired
amount_eurnumberrequired

Additional properties: not allowed.

stt_chargeobjectoptional
nullable true
View nested fields
transaction_idstringrequired

Public transaction reference matching your ledger, or null when no balance movement exists.

nullable truepattern "^TX-[A-F0-9]{12,24}$"
productstringrequired
duration_secondsintegerrequired
billed_minutesintegerrequired
rate_per_min_eurnumberrequired
amount_eurnumberrequired

Additional properties: not allowed.

digitsstringoptional

Captured keypad digits for input dtmf.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "success"
      ]
    },
    "call_control_id": {
      "type": "string",
      "nullable": false
    },
    "input": {
      "type": "string",
      "enum": [
        "speech",
        "dtmf"
      ]
    },
    "transcript": {
      "type": "string"
    },
    "tts_charge": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "transaction_id": {
          "type": "string",
          "nullable": true,
          "pattern": "^TX-[A-F0-9]{12,24}$",
          "description": "Public transaction reference matching your ledger, or null when no balance movement exists."
        },
        "product": {
          "type": "string"
        },
        "characters": {
          "type": "integer"
        },
        "rate_per_char_eur": {
          "type": "number"
        },
        "amount_eur": {
          "type": "number"
        }
      },
      "required": [
        "transaction_id",
        "product",
        "characters",
        "rate_per_char_eur",
        "amount_eur"
      ],
      "nullable": true
    },
    "stt_charge": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "transaction_id": {
          "type": "string",
          "nullable": true,
          "pattern": "^TX-[A-F0-9]{12,24}$",
          "description": "Public transaction reference matching your ledger, or null when no balance movement exists."
        },
        "product": {
          "type": "string"
        },
        "duration_seconds": {
          "type": "integer"
        },
        "billed_minutes": {
          "type": "integer"
        },
        "rate_per_min_eur": {
          "type": "number"
        },
        "amount_eur": {
          "type": "number"
        }
      },
      "required": [
        "transaction_id",
        "product",
        "duration_seconds",
        "billed_minutes",
        "rate_per_min_eur",
        "amount_eur"
      ],
      "nullable": true
    },
    "digits": {
      "type": "string",
      "description": "Captured keypad digits for input dtmf."
    }
  },
  "required": [
    "status",
    "call_control_id",
    "input",
    "tts_charge"
  ]
}
400 The request failed validation.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
401 The API key or browser token is missing or invalid.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
402 The account has insufficient available credit.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
403 The account is not allowed to perform this operation.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
404 The requested owned resource was not found.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
409 The request conflicts with an earlier request, is in progress, or has finished unsuccessfully. Only error_code voice_request_closed confirms billing is settled and permits a new request with a new key.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
429 The request rate limit was exceeded.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
500 An unexpected service error occurred.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}
503 For voice_request_pending, keep the same request key while the outcome is checked. For voice_billing_review, contact support before trying again.

application/json

statusstringrequired
enum ["error"]
messagestringrequired
error_codestringoptional

Public incident or validation code when the endpoint provides one.

nullable true
fieldsobjectoptional

Public validation details when supplied by the endpoint.

Additional properties: not allowed.

Full schema
Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "status",
    "message"
  ],
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "error_code": {
      "type": "string",
      "nullable": true,
      "description": "Public incident or validation code when the endpoint provides one."
    },
    "fields": {
      "type": "object",
      "additionalProperties": true,
      "description": "Public validation details when supplied by the endpoint."
    }
  }
}

Sandbox scenarios

Use https://sandbox-api.illyvoip.com with Sandbox credentials and the X-Illyvoip-Sandbox-Scenario header. Omit the header for the documented success default. This header belongs to sandbox requests.

success, not-found, rate-limited, forbidden, service-unavailable, insufficient-credit, idempotency-conflict

Try this operation in Sandbox · Environment setup and limitations

Search API operations, parameters, SDK and webhooks.