DEV Community

Cover image for Route Phone Calls to an AI Agent With the Telnyx Voice API
Harpreet Singh Seehra
Harpreet Singh Seehra

Posted on

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

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.

What Is Call Control?

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.

How It Works

The call flow has three 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'll use for all subsequent commands on this call.

  2. 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.

  3. 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.

Key API Calls

Everything below works with any language or framework. All you need is the ability to receive HTTP requests and make HTTP requests.

Answer an Inbound Call

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"
Enter fullscreen mode Exit fullscreen mode

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.

Speak to the Caller (TTS)

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"
  }'
Enter fullscreen mode Exit fullscreen mode

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 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"
Enter fullscreen mode Exit fullscreen mode

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 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.

Why Telnyx

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.

Get Started

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:

  1. Sign up for a Telnyx account if you don't have one.
  2. Buy a phone number and create a Call Control Application in the Mission Control Portal, setting your webhook URL to point to your /webhooks/call endpoint.
  3. Clone the example repo, set your TELNYX_API_KEY and TELNYX_PUBLIC_KEY environment variables, and run the app.

Full API documentation is available at developers.telnyx.com.

Top comments (0)