connic voice
connic voice integrates native voice models with the familiar connic agent configuration.
On this page
Native voice models process audio directly and respond with speech. Select one through model and add voice_config for voice, greeting, and conversation settings. Configure prompts and tools as with any other agent.
Configure an agent
version: "1.0"
name: voice-assistant
type: llm
model: openai/gpt-realtime-2.1
description: "A helpful voice assistant"
system_prompt: |
Keep replies short and natural. Reply in the user's language.
Before using a tool, briefly say what you are checking,
then call the tool in the same response.
Say goodbye before ending the conversation.
voice_config:
transcription_model: gpt-realtime-whisper
greeting: "Hi! How can I help?"
thinking_sound: trueDeploy the agent, then link a connector that supports voice. A voice connector in sync mode answers calls; in outbound mode, every run of the agent calls the number in its input. An empty voice_config: {} also enables voice with defaults. Without a greeting, the agent waits for the other side to speak first, on incoming and outgoing calls alike.
Voice configuration
All settings belong inside voice_config. This example uses an OpenAI voice; choose a voice supported by your model provider. The table lists the defaults when a setting is omitted.
model: openai/gpt-realtime-2.1
voice_config:
voice: alloy
language: en
transcription_model: gpt-realtime-whisper
greeting: "Hi! How can I help?"
thinking_sound: true
hang_up_allowed: true
press_keys_allowed: true
wait_on_hold_allowed: true
max_hold_seconds: 1800
turn_detection:
silence_ms: 500
interruptions:
enabled: true
min_speech_ms: 500
idle_timeout_seconds: 60| Field | Type | Status | Description |
|---|---|---|---|
| voice | string | Optional | Voice ID accepted by the selected provider. Omit to use its default voice. |
| language | string | Optional | Preferred spoken language as a code such as en or de-DE. connic adds it to the model instructions, which set the language the agent speaks, and passes it to the provider's transcription of the other side's speech. Recognition still follows the language spoken. |
| transcription_model | string | Optional | OpenAI model name for transcribing user speech, or an existing transcription deployment name in the same Azure resource. Omit to disable user transcription for OpenAI and Azure. Gemini, Vertex AI, and connic/gemini-3.8-live use native transcription without this setting. |
| greeting | string | Optional | Opening greeting requested from the model. Omit to let the user speak first. |
| thinking_sound | boolean | Optional | Play a quiet repeating tone during tool waits or provider-reported background work. Pauses while the user or agent speaks.Default: true |
| hang_up_allowed | boolean | Optional | Allow the agent to end the conversation itself. A spoken farewell plays in full before the conversation ends. Set false to disable this ability.Default: true |
| press_keys_allowed | boolean | Optional | Give the agent the press_keys tool to press phone keys, such as in a phone menu. See Phone menus.Default: true |
| wait_on_hold_allowed | boolean | Optional | Give the agent the wait_on_hold tool to wait in a queue or on hold until a person answers. See Waiting on hold.Default: false |
| max_hold_seconds | integer | Optional | End the call once the agent has waited on hold this long, from 1 to 3600 seconds. Requires wait_on_hold_allowed. Omit to wait until the run timeout. |
| turn_detection | object | Optional | Control detection of when the user has finished speaking. |
| silence_ms | integer | Optional | Silence duration in milliseconds before ending the user's turn. Must be greater than zero.Default: 500 |
| interruptions | object | Optional | Control whether user speech interrupts the spoken response. Interruptions are enabled when this object is omitted. |
| enabled | boolean | Required | Whether the user can interrupt the agent. Required when interruptions is present. |
| min_speech_ms | integer | Optional | How long the user must keep speaking while the agent talks before the agent stops, from 0 to 5000 milliseconds. Shorter sounds, such as a cough or background noise, don't interrupt the agent.Default: 500 |
| idle_timeout_seconds | integer | Optional | End the call after this many seconds without speech. Only speech counts: the agent's speech and the other side's transcribed speech. Running tools, provider-reported background work, and waiting on hold keep the call open. Must be greater than zero. Omit for no voice-specific idle timeout; the run timeout still applies. |
| keypad | object | Optional | Map keypad keys (0-9, *, #) to tools listed in tools. A key press runs its tool without a model turn. See Keypad input. |
Every option is optional, except interruptions.enabled when the interruptions object is present.
Models and providers
| Provider | Models |
|---|---|
| connic | Managed voice models billed from Project credit (e.g. connic/gemini-3.8-live) |
| OpenAI | OpenAI Realtime models (e.g. openai/gpt-realtime-2.1) |
| Azure OpenAI | OpenAI Realtime models on Azure (e.g. azure/gpt-realtime-2.1) |
| Google Gemini | Gemini native audio models (e.g. gemini/gemini-3.8-live) |
| Google Vertex AI | Gemini native audio models on Vertex AI (e.g. vertex_ai/gemini-3.8-live) |
Use connic/ followed by a managed voice model, which needs no provider credentials. With your own credentials, use openai/, azure/, gemini/, or vertex_ai/ followed by the model or Azure deployment name; the provider checks whether it is available and supports realtime audio. Voice names depend on the model; omitting voice keeps its default. connic/gemini-3.8-live takes Gemini voice names such as Kore.
Set reasoning_effort on the agent to request a reasoning level. connic passes the setting to the provider, which rejects unsupported settings or values. Omit it or use auto for the model default. For example, gemini/gemini-3.8-live-extended-thinking supports low, medium, and high.
Data location
Where the model and the phone provider process a call depends on their own settings:
- connic voice models run in the EU. The provider keeps a call's session for up to 24 hours so that long calls can continue when the connection to the model is renewed.
- Vertex AI runs the model in the location saved with the project's Vertex AI credentials. Set it to
eu, the EU multi-region, to keep processing in the EU. - Azure OpenAI runs the model in the region of your Azure resource. Create the resource in an EU region and deploy the model as a Data Zone deployment.
- OpenAI takes calls on its standard endpoint, which has no region setting.
- Gemini with an API key has no region setting. Use Vertex AI to choose the location.
- Twilio: the Connection's region only selects the Twilio API that connic uses. Which Twilio region handles a call is set on the number in Twilio.
- Telnyx routes call audio through the AnchorSite of the call's Call Control application. Set a European site on the application in the Telnyx portal; connic leaves this setting unchanged.
- SIP calls take the route of your phone system or provider.
Billing
A call is one run. connic bills the run start and the runtime per second, from the start of the run to the end of the call, so the ringing of an outgoing call and any time on hold count. There is no separate voice fee. With a connic/* voice model, connic bills its audio and text tokens from Project credit at the prices in the model catalog, and the call ends when the credit runs out. With your own credentials, the model provider bills the tokens to your account. The phone provider bills the call. See Pricing.
Tools and conversation flow
Voice agents use the existing tool execution path: Python tools, retrieval, MCP servers, conditional tools, discoverable tools, tool hooks, and delegation. Middleware runs around the whole run.
A short spoken acknowledgement before a tool call helps explain a wait. By default, a quiet repeating tone plays during tool waits or provider-reported background work and pauses while either participant speaks. Set thinking_sound: false to disable it.
connic doesn't store call audio. The transcript is the run's output: the run details show agent speech and, when transcription is enabled, user speech as text. Transcription failures appear there as errors while the conversation continues. The traces show which tools the agent used and how long each step took, along with reasoning summaries when the provider returns them. The audio and text tokens the provider reports for each response appear in the run's token usage and in Token Usage.
Call details
An outgoing call belongs to the run that placed it, which keeps its own input. Its context holds no call ID or phone numbers, and context["connector_id"] is the connector that started the run, not the voice connector. Put what the agent needs to know, such as why it calls, in the run input. An incoming phone call starts the run with these call details as its input:
{
"call_id": "<provider call ID>",
"from": "+4915112345678",
"to": "+4930123456789",
"provider": "<voice connector>",
"caller_name": "Alex Example",
"forwarded_from": "+4940123456789",
"raw": {}
}call_id is the provider's identifier for the call, and provider names the voice connector that received it. caller_name and forwarded_from appear only when the provider sends a caller name or the number that forwarded the call. raw contains the provider's complete incoming-call request. Each voice connector's page describes what its provider sends.
Middleware reads the details from context["payload"] and tools from their context parameter. The model receives them as the first message unless before middleware replaces it. Middleware can identify the caller, store the result in context, and use conditional tools to decide which tools the agent gets.
Transferring a call
A tool or tool hook transfers the caller by raising TransferCall with a phone number in E.164 format. Speech that is already playing finishes first. The number must be one of the voice connector's transfer numbers; otherwise the tool call returns an error and the agent can tell the caller.
from connic import TransferCall
def transfer_to_sales(context: dict) -> str:
"""Transfer the caller to the sales team."""
raise TransferCall("+4930123456789")Any conditions for the transfer belong in the tool. In the Playground, the session ends and shows the number instead of dialing it. If the transfer number doesn't answer, the call ends. Voice connectors in sync mode can also forward incoming callers to a fallback number when the agent can't take or finish a call. The fallback number covers neither transfers nor outgoing calls.
The transfer ends the run normally, so after middleware still runs. The trace shows the transfer and its number on the tool's step. context does not record it. If after needs to know, the tool sets a key such as context["transferred_to"] before raising TransferCall.
Keypad input
keypad maps keys to tools. A key press runs its tool directly, without a model turn, so it works at any point in the call, including during the greeting. Each tool must be listed in tools and cannot have required parameters. When a keypad tool raises TransferCall, current speech stops and the call is transferred immediately.
tools:
- phone.transfer_to_sales
- phone.transfer_to_operator
voice_config:
greeting: "Welcome. To reach an operator, press 0 at any time."
keypad:
"0": phone.transfer_to_operatorEvery key press is recorded in the run. Keys without a mapping, and keys whose conditional tool was not selected for the call, run nothing. The Playground shows a keypad during voice sessions.
Phone menus
The agent presses phone keys with the built-in press_keys tool, for example to choose an option in a phone menu or to enter a number it asks for. It takes the keys 0-9, *, and #, and w for a half-second pause, up to 64 at a time, such as 1w2#. The keys play on the call in order, and the agent then waits for the menu to answer. Every press is recorded in the run, and the traces show the keys on the tool's step.
The tool works the same on every voice connector. In the Playground, the keys are shown instead of sent. Set press_keys_allowed: false to remove the tool.
Waiting on hold
With wait_on_hold_allowed: true, the agent gets the built-in wait_on_hold tool. It calls the tool once the call is in a queue or on hold. While it waits, the voice model gets no audio, so the provider bills no tokens, and the agent makes no replies. Waiting doesn't count toward max_iterations or idle_timeout_seconds.
system_prompt: |
You call suppliers to ask when an open order ships.
In a phone menu, choose the option for order status with press_keys.
When you are put on hold, call wait_on_hold. When a person answers,
say who you are and which order you are calling about.
voice_config:
language: de-DE
wait_on_hold_allowed: true
max_hold_seconds: 2400connic listens to the line for the person who answers. A person greets and then pauses for a reply, while music and recorded announcements keep playing. Once speech is followed by a quiet line, connic wakes the agent and passes it that speech, so it can answer the greeting. When a recording wakes the agent and it goes back on hold without speaking, connic recognizes that recording and doesn't wake the agent for it again. The detection works the same on every provider. The run records each wake-up and how long the agent waited.
An announcement that ends in a quiet pause, such as one on a line without hold music, wakes the agent the first time it plays; a person who answers over loud background noise can take a moment longer to be noticed. Tell the agent in its prompt to call wait_on_hold again when music or a recording woke it.
max_hold_seconds ends the call once a wait lasts that long, and the run fails with the reason. A wait lasts from the first wait_on_hold until the agent speaks after waking.
Ending a conversation
The agent can end the conversation itself. A spoken farewell plays in full before the conversation ends. The prompt can describe when the agent should end the conversation. To disable this ability:
voice_config:
hang_up_allowed: falseCall length
A conversation is one run, so the agent's timeout, capped by the plan's run timeout, sets its maximum length. On Pro, that is 60 minutes. The call ends when it is reached. Each reply of the agent counts toward max_iterations; replies that only go back on hold don't.
Calls longer than about 15 minutes on Gemini, Vertex AI, and connic/gemini-3.8-live need context_compression; without it, the provider ends the call. With it, the provider drops or summarizes the oldest part of the call and keeps the instructions. On voice agents, context_compression takes enabled and max_prompt_tokens, which starts compressing once the call reaches that many tokens. OpenAI and Azure OpenAI drop the oldest turns once a call fills the context window; max_prompt_tokens sets how many tokens they keep.
context_compression:
max_prompt_tokens: 20000Current limitations
Voice requires type: llm and a voice model from connic, OpenAI, Azure OpenAI, Google Gemini, or Google Vertex AI. Other connic/* models don't support voice. Input and output guardrails, human approvals, structured output (output_schema or output_schema_dict), and fallback_model are rejected for voice agents. Audio reaches the model and user as it streams, so those guardrails cannot inspect it before delivery.
Automated agent tests do not support voice sessions yet. Test the deployed agent in a live conversation.