Twilio Voice
Put a voice agent on the Twilio number you already have. connic sets the incoming-call webhook and streams the audio, and the agent answers with your knowledge and tools.
- Publisher
- By connic
- Modes
- Sync
- Set up in
- Dashboard or connectors/*.yaml
- Documentation
- Twilio Voice docs
Answer calls on the number you already have
Connect your Twilio account, pick a voice-capable number and link one voice agent. connic points the number at the agent and carries the audio both ways.
- A reusable Twilio Connection
- Save the Account SID, the region (US1, IE1 or AU1) and that region's Auth Token once, then use the Connection for other numbers in the same account and region.
- What connic changes in Twilio
- Saving sets the number's incoming-call webhook with HTTP POST. An existing webhook or TwiML App is replaced, and the previous values go to the connector logs. Deleting the connector clears the webhook only if it still points to connic.
- Before you connect
- Take the number out of any SIP trunk, and pick one whose incoming-call region matches the Connection. Each number belongs to one active connector.
The caller dials your number
Twilio receives the call and requests the incoming-call webhook that connic set on the number.
connic checks the request
The Auth Token verifies Twilio's signature. While the connector is paused or the environment has no active deployment, Twilio uses the number's Primary handler fails setting instead.
The agent picks up
connic starts a run with the call details and streams audio both ways. The agent greets the caller, listens and uses its tools.
The call ends or moves on
The agent says goodbye and hangs up, or transfers the caller to one of your numbers. If the run fails, Twilio dials your fallback number.
Tune how the agent sounds and listens
Voice settings live in voice_config next to the agent's prompt and tools, so one deploy ships both.
- Realtime models
- Use connic/gemini-3.8-live without provider credentials, billed from Project credit. With your provider credentials in the project, use an OpenAI or Azure OpenAI realtime model, or a Gemini native audio model through Google Gemini or Vertex AI.
- Turn-taking
- silence_ms sets how long the caller can pause before the agent answers. With interruptions on, which is the default, the caller can talk over the agent.
- Ending the call
- The agent can hang up after a farewell, which always plays in full. Set hang_up_allowed to false to turn that off, and idle_timeout_seconds to end a call that goes quiet.
- What voice agents leave out
- Guardrails, human approvals, structured output, fallback_model and context_compression are rejected for voice agents. A call is one run, so the agent's timeout caps its length.
version: "1.0"
name: support-voice
type: llm
model: openai/gpt-realtime-2.1
description: Answers calls on the support line
system_prompt: |
Keep replies short and natural.
Before you use a tool, say what you are checking.
Say goodbye before you end the call.
tools:
- retrieval_query
- orders.get_order_status
voice_config:
voice: alloy
language: en
transcription_model: gpt-realtime-whisper
greeting: "Hi, you're through to support. How can I help?"
turn_detection:
silence_ms: 500
interruptions:
enabled: true
idle_timeout_seconds: 60
hang_up_allowed: trueKnow who is calling and pass them on
Every run starts with the call details, and your tools decide when a caller should talk to a person.
- Call details
- call_id holds the CallSid, and raw holds Twilio's full request. caller_name needs caller ID lookup on the number, and forwarded_from appears when the carrier passes the forwarding number.
- Transfers
- A tool raises TransferCall with one of up to 20 transfer numbers on the connector, and Twilio dials it once the current speech finishes. Any other number returns an error the agent can explain.
- Keypad
- Map the keys 0-9, * and # to tools in voice_config. A key press runs its tool without a model turn, even during the greeting.
- Fallback number
- When an accepted call can't continue, for example because the run fails or the caller waited the maximum wait, Twilio dials this number. Without one, the call ends.
{
"call_id": "CA1234567890abcdef1234567890abcdef",
"from": "+4915112345678",
"to": "+4930123456789",
"provider": "twilio",
"caller_name": "Alex Example",
"raw": {
"CallSid": "CA1234567890abcdef1234567890abcdef",
"From": "+4915112345678",
"To": "+4930123456789",
"CallerName": "Alex Example"
}
}from connic import TransferCall
def transfer_to_support(context: dict) -> str:
"""Transfer the caller to the support team."""
raise TransferCall("+4930123456780")tools:
- phone.transfer_to_support
voice_config:
greeting: "Hi! Press 0 at any time to reach our team."
keypad:
"0": phone.transfer_to_supportKeep the phone line in your codebase
Declare the connector in connectors/ with the number in E.164 format. The deploy looks the number up in the named Connection and fails if another active connector already uses it. The Auth Token never appears in the file.
type: twilio
name: Support line
connection: support-twilio
config:
phone_number: "+4930123456789"
transfer_numbers:
- "+4930123456780"
fallback_number: "+4930123456781"
agents:
- support-voiceWhat callers can get done
Pick a setup to see the call path and the agent YAML behind it.
Callers ask how something works, and the agent answers from the product docs it retrieves.
version: "1.0"
name: product-support
type: llm
model: openai/gpt-realtime-2.1
description: Answers product questions by phone
system_prompt: |
Answer from the product docs you retrieve.
Keep each answer to a few sentences.
tools:
- retrieval_query
voice_config:
transcription_model: gpt-realtime-whisper
greeting: "Hi! What can I help you with today?"The agent asks for the order number, checks your order system and reads the status back.
version: "1.0"
name: order-status
type: llm
model: openai/gpt-realtime-2.1
description: Tells callers where their order is
system_prompt: |
Ask for the order number and the postcode.
Say that you are checking, then look the order up.
tools:
- orders.get_order_status
voice_config:
greeting: "Hi! Do you have your order number handy?"
idle_timeout_seconds: 60The agent offers free slots, confirms the caller's choice and books it with your calendar tool.
version: "1.0"
name: appointment-desk
type: llm
model: openai/gpt-realtime-2.1
description: Books appointments by phone
system_prompt: |
Offer at most three free slots at a time.
Repeat the chosen slot before you book it.
tools:
- calendar.find_free_slots
- calendar.book_slot
voice_config:
greeting: "Hi! When would you like to come in?"
turn_detection:
silence_ms: 700Callers press 0 or ask for a person, and a tool transfers them to your support line.
version: "1.0"
name: front-desk
type: llm
model: openai/gpt-realtime-2.1
description: Answers first and hands over when asked
system_prompt: |
Help with general questions.
If the caller asks for a person, transfer them.
tools:
- phone.transfer_to_support
voice_config:
greeting: "Hi! Press 0 at any time to reach our team."
keypad:
"0": phone.transfer_to_supportTwilio Voice FAQ
More connectors
Apache Kafka
By connicConsume topics to trigger agents and produce results back to topics under the source message key.
InboundOutboundEmail (SMTP/IMAP)
By connicRead an inbox to trigger an agent. Reply with a drafted message over SMTP. Attachments included.
InboundOutboundHTTP Webhooks
By connicRun an agent on any HTTP request with JSON, form data, or file uploads. No glue server is required.
InboundOutboundSyncMCP Server
By connicExpose agents as MCP tools. MCP clients list and call them and get the agent's answer as the tool result.
InboundSyncPostgreSQL
By connicUse LISTEN/NOTIFY to trigger an agent from new rows, without polling or a CDC pipeline.
InboundTwilio Messaging
By connicReceive SMS, MMS, WhatsApp, and RCS messages with an agent. Send replies, media, and WhatsApp templates through your Twilio account.
InboundOutbound