Route Phone Calls to an AI Agent With the Telnyx Voice API Telnyx has introduced Call Control, a webhook-driven API that enables developers to route inbound phone calls to AI agents. The API provides real-time event handling and command issuance for call states, allowing integration of speech-to-text, LLM processing, and text-to-speech within the call flow. This infrastructure layer is essential for building voice AI agents that can answer, respond, and manage calls programmatically. Voice AI agents are transforming customer service, sales, and support. But before an AI can talk to a caller, you need the voice infrastructure layer — a way to receive inbound phone calls, control the call flow, and respond programmatically. Without this foundation, your AI model has no way to pick up the phone. Telnyx Call Control gives you this through webhooks. When someone calls your Telnyx number, your application receives events in real time and issues commands back — answer, speak, gather input, transfer, or hang up. This is the foundation every voice AI agent runs on. 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 works like this: Telnyx sends a webhook to your application, your app processes the event, your app issues a Call Control command, and Telnyx sends the next event when that command completes. This cycle repeats for the life of the call. This event-driven pattern is what makes voice AI possible. Your app can insert AI inference — speech-to-text, LLM processing, text-to-speech — between receiving a caller's input and responding. The Call Control webhook loop gives you a hook into every moment of the conversation. The call flow has three steps: 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'll use for all subsequent commands on this call. Your application answers and responds. Your webhook handler calls the answer action to connect the call, then speak to play a text-to-speech message to the caller. Each command triggers the next webhook event when it completes — call.answered confirms the call connected, call.speak.ended confirms the TTS finished. The call completes. When the TTS finishes, Telnyx sends a call.speak.ended event. Your app issues hangup to end the call. The call.hangup event confirms cleanup. One webhook endpoint. A state machine driven by events. Everything below works with any language or framework. All you need is the ability to receive HTTP requests and make HTTP requests. When you receive a call.initiated webhook, answer the call with: 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's the handle you use to issue every subsequent command on this call. Once the call is connected, play a text-to-speech message: 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. When you're done, terminate the call: 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. Telnyx signs every webhook request with an Ed25519 signature. Your application should verify this signature before processing the event to ensure the request actually came from Telnyx. The Telnyx SDKs handle this automatically — in Python, for example, you 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 https://portal.telnyx.com . Webhook-driven, not poll-driven. Every call state change arrives as an HTTP event — call.initiated , call.answered , call.speak.ended , call.hangup . Your app stays in control without polling or long-lived connections. Full call control vocabulary. Answer, speak, gather DTMF or speech, transfer, conference, record — one API covers the entire call lifecycle. The same webhook loop works whether you're building a simple greeting or a multi-turn AI agent. Private network infrastructure. Telnyx operates a private global IP network. Voice traffic doesn't traverse the public internet, reducing latency and improving call quality. No per-minute markup games. Telnyx pricing is straightforward. You pay for what you use without inflated per-minute fees or hidden platform surcharges. A complete working example — a Python Flask application that implements webhook signature verification, Call Control event handling, text-to-speech, and error handling — is available in the Telnyx code examples repository: route-phone-calls-to-ai-agent-python on GitHub The example includes a webhook endpoint /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. Clone it, add your credentials, and you have a running voice webhook handler. To get started: /webhooks/call endpoint. TELNYX API KEY and TELNYX PUBLIC KEY environment variables, and run the app.Full API documentation is available at developers.telnyx.com https://developers.telnyx.com .