Voice

Route Phone Calls to an AI Agent With the Telnyx Voice API

Route inbound phone calls to an AI agent with Telnyx Call Control. Webhook-driven voice infrastructure: answer, speak, gather input, and hang up programmatically.

By Harpreet Singh Seehra

To route phone calls to an AI agent, connect Telnyx Phone Numbers, available in 140+ countries with instant activation, to a Call Control Application. Telnyx sends call control webhooks to your app. Your app answers the call with call_control_id, runs agent logic, then sends commands back to Telnyx. The Telnyx Voice API provides programmable voice with WebSocket support, SIP and PSTN, and global coverage. Telnyx Voice AI adds sub-500ms latency, multi-model support, and co-located infrastructure when you want a managed voice AI agent.

This guide covers the voice infrastructure layer. You will see the webhook loop, the exact Call Control API actions for answer, speak, and hangup, and where to place AI inference. The sample app uses Python Flask and follows the route-phone-calls-to-ai-agent-python example.

Note: The curl examples below are the minimal call path from the original sample. The sample answers an inbound call, speaks a TTS message, and hangs up. Insert your AI agent logic in the same event loop.

Route phone calls to AI agent workflow

A voice AI agent cannot answer a PSTN call by itself. It needs a carrier layer, a webhook endpoint, and call commands. Telnyx handles the carrier layer. Your application handles state and business rules. The AI agent handles dialog decisions.

Call Control flow

Caller calls Telnyx number
call.initiated webhook
App sends answer
call.answered event
Speak or agent logic
call.speak.ended event
App sends hangup

Call flow steps

  1. A customer calls your Telnyx number. Telnyx sends a call.initiated webhook to your application with the caller's number, your number, and a call_control_id you use for later commands on this call.
  2. Your application answers. Your webhook handler calls POST /v2/calls/{call_control_id}/actions/answer. Telnyx sends call.answered when the call connects.
  3. Your application responds. The sample calls POST /v2/calls/{call_control_id}/actions/speak with payload, voice, and language_code. Telnyx sends call.speak.ended when playback finishes.
  4. Your application ends the call. It calls POST /v2/calls/{call_control_id}/actions/hangup. Telnyx sends call.hangup. The hangup_reason field tells you why the call terminated.

Call Control API basics

Telnyx Call Control is a webhook-driven API for programmable voice. Instead of static IVR menus, your application receives HTTP events for every call state change and responds with commands.

The event loop is direct. Telnyx sends a webhook to your application. Your app processes the event. Your app issues a Call Control command. Telnyx sends the next event when that command completes. This cycle repeats for the life of the call.

This pattern is what makes inbound call automation practical. Your app can put model inference, CRM lookup, fraud checks, routing rules, or text-to-speech between the event and the command. For a broader build path, read the Voice API guide.

Core API calls

Everything below works with any language or framework. You need an HTTP endpoint to receive webhooks and an HTTP client to send Call Control commands.

Answer an inbound call

When you receive a call.initiated webhook, answer the call with this command.

bash
curl -X POST https://api.telnyx.com/v2/calls/{call_control_id}/actions/answer \
 -H "Authorization: Bearer YOUR_TELNYX_API_KEY" \
 -H "Content-Type: application/json"

The call_control_id comes from the call.initiated webhook payload. It is the handle you use to issue every later command on this call.

Speak to the caller

Once the call is connected, play a text-to-speech message.

bash
curl -X POST https://api.telnyx.com/v2/calls/{call_control_id}/actions/speak \
 -H "Authorization: Bearer YOUR_TELNYX_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "payload": "Thank you for calling. Your call is important to us. Goodbye.",
 "voice": "female",
 "language_code": "en-US"
 }'

The payload field is the text to speak. The voice field accepts female or male. The language_code field controls the language and accent. en-US, en-GB, es-ES, and others are supported. When playback finishes, Telnyx sends a call.speak.ended webhook event.

Hang up the call

When the flow is done, terminate the call.

bash
curl -X POST https://api.telnyx.com/v2/calls/{call_control_id}/actions/hangup \
 -H "Authorization: Bearer YOUR_TELNYX_API_KEY" \
 -H "Content-Type: application/json"

Telnyx sends a call.hangup event to confirm the call has ended. The hangup_reason field in the event payload tells you why the call terminated.

Webhook signature verification

Telnyx signs every webhook request with an Ed25519 signature. Your application should verify this signature before processing the event. That check rejects requests that did not come from Telnyx.

The Telnyx SDKs handle this automatically. In Python, call client.webhooks.unwrap() with the raw request body and headers. This requires the TELNYX_PUBLIC_KEY environment variable, which you can find in the Mission Control Portal.

Note: Keep the raw request body unchanged before verification. Parsing and reserializing JSON can change the bytes the signature was created against.

Number and trunking setup

Most inbound AI flows start with a Telnyx number. Buy or port the number, assign it to a Call Control Application, and set your webhook URL to your /webhooks/call endpoint.

Existing PBX traffic can come through Telnyx SIP Trunking, an enterprise-grade service with a 99.999% uptime SLA. Keep SIP for agents or legacy queues, then route selected calls into programmable voice when automation should answer. For migration basics, read the SIP trunking guide.

Teams building for contact centers can route by number, queue, department, or caller intent. Start with one flow. Measure containment and transfer rate. Expand when the data supports it.

Build options compared

OptionBest fitControl model
Static IVRSimple menus with fixed pathsConfiguration driven
Call Control APICustom inbound call automationWebhook events plus commands
Voice AIManaged voice AI agent flowsAgent runtime on Telnyx voice infrastructure

Where the AI agent fits

The sample app speaks a fixed sentence. A production voice AI agent replaces that decision point. After your app receives an event or caller input, it calls your model or managed agent. The returned decision maps to a Call Control command.

Wait for call_control_id before sending commands. Verify signatures first. Treat call.speak.ended as the signal that TTS playback has finished before issuing the next command.

Why Telnyx for voice AI

Webhook-driven

Every call state change arrives as an HTTP event. Your app stays in control without polling or long-lived connections.

Full call control

Answer, speak, gather DTMF or speech, transfer, conference, record. One API covers the entire call lifecycle.

Private network

Telnyx operates a private global IP network. Voice traffic avoids unnecessary public internet hops, reducing latency and improving call quality.

Transparent pricing

Pay for what you use. No inflated per-minute fees or hidden platform surcharges.

Static IVR vs Call Control

FeatureStatic IVRCall Control
Call flowFixed menu treeProgrammable state machine
AI integrationLimited or bolted onNative, inserted between events
Response logicPre-recorded promptsDynamic TTS, any voice or language
ScalabilityMenu depth limitsUnlimited conversation turns

Try the example app

Telnyx provides a working Python Flask example that implements webhook signature verification, Call Control event handling, text-to-speech, and error handling. Clone the route-phone-calls-to-ai-agent-python example from GitHub.

The example includes a webhook endpoint at /webhooks/call, a state machine that answers inbound calls and plays a TTS greeting, and proper error handling for authentication, rate limiting, and API errors.

Getting started

Setup checklist:
  1. Sign up for a Telnyx account
  2. Buy a phone number and create a Call Control Application in the Mission Control Portal
  3. Set your webhook URL to point to your /webhooks/call endpoint
  4. Clone the example app
  5. Set your TELNYX_API_KEY and TELNYX_PUBLIC_KEY environment variables
  6. Run the app and call your Telnyx number

Full API documentation is available at developers.telnyx.com. For more on messaging automation, see the SMS auto-reply bot and WhatsApp OTP guides.

FAQ

What is Telnyx Call Control?
Telnyx Call Control is a webhook-driven API for programmable voice. When someone calls your Telnyx number, Telnyx sends HTTP events to your application for every call state change. Your app processes each event and issues commands back: answer, speak, gather input, transfer, or hang up.
How do I connect an AI model to inbound calls?
Use the Call Control webhook loop. When Telnyx sends a call.initiated event, your app answers the call. When the caller speaks, your app sends the audio to your speech-to-text provider, passes the transcript to your LLM, and uses the speak command to play the LLM response back to the caller. Telnyx Voice AI co-locates this entire stack for sub-500ms latency.
Do I need to verify Telnyx webhook signatures?
Yes. Telnyx signs every webhook request with an Ed25519 signature. Verify this signature before processing any event. The Telnyx SDKs handle this automatically. In Python, call client.webhooks.unwrap() with the raw request body and headers. You need the TELNYX_PUBLIC_KEY from the Mission Control Portal.
What programming languages can I use?
Any language or framework that can receive HTTP requests and make HTTP requests. The Call Control API is REST-based. The example app is written in Python with Flask, but the same webhook pattern works in Node.js, Go, Ruby, PHP, Java, or any other language.
What call control commands are available?
The Call Control API supports answer, speak (TTS), gather DTMF or speech input, transfer, conference, record, play audio, and hangup. One API covers the entire call lifecycle, from the first ring to cleanup.

Route calls to your AI agent todayOne webhook endpoint. Full call control. Sub-500ms latency with co-located Voice AI.

Get started free
Share on Social

Sign up for emails of our latest articles and news