---
title: Build an AI agent for SMS, Email, and Phone Calls
canonical: https://telnyx.com/ai-agents/build-omnichannel-ai-agent
---
# Build an AI agent for SMS, Email, and Phone Calls

[Back to AI agents](https://telnyx.com/ai-agents)

**Conversational AI**

# How to build an omnichannel AI agent

Build one AI agent that emails, texts, and calls customers with one shared memory. A Python tutorial using one Telnyx API key.

By [Deniz Yakisikli](https://telnyx.com/authors/deniz-yakisikli-61)

Takeaways

This tutorial builds one AI agent that emails, texts, and calls your customer in the same conversation, and remembers every message across all three channels.

* The agent picks the channel per message: email for the record, SMS for speed, a voice call when the matter is complex or urgent.
* One API key covers the brain and all three channels, with no second provider and no second bill.
* A demo mode runs the entire flow with zero credentials, so you can watch the agent plan its outreach before you write a single line of config.
  
  
A 6am flight cancellation sets off a scramble. The traveler wants rebooking options, a written record, and quick answers while they commute. The same conversation might need a detailed email, a short text, and a phone call, all within an hour.

Customers already live across channels. According to [a recent CX Trends report](https://cxtrends.zendesk.com/), 74% of consumers now expect customer service to be available around the clock, and 76% say they would choose a company that lets them keep everything in one thread instead of restarting on every channel.

Most teams answer by bolting three separate bots onto three channels. The email autoresponder knows nothing about the SMS thread. The SMS thread knows nothing about the call. The customer feels the gap and repeats their story every time.

This tutorial takes a different approach: one AI agent that emails, texts, and calls customers with shared memory across all three, built in about 700 lines of Python behind a single Telnyx API key.

## What is an omnichannel AI agent?

An omnichannel AI agent is a single AI system that reaches a customer across email, SMS, and voice while keeping one conversation memory across every channel. It decides which channel fits each message, writes the content, and references what it already said elsewhere.

Omnichannel is the word that matters. Multichannel means you offer many channels. Omnichannel means the customer's context follows them between those channels. The difference shows up in how the agent behaves:

| Multichannel setup                  | Omnichannel agent                         |
| ----------------------------------- | ----------------------------------------- |
| One bot per channel                 | One agent across channels                 |
| No shared history                   | One conversation memory for all channels  |
| Customer repeats their story        | Agent references earlier messages         |
| Channel choice made by the customer | Agent picks the right channel per message |

## What you'll build

The app is a small Python service, built with a web framework called Flask, that runs a customer service AI agent for a fictional demo company, TelnyxDemo Corp. You hand it a customer scenario in plain language, and it plans the outreach itself:

* **Email** for formal acknowledgments, detailed explanations, and anything that needs a written record
* **SMS** for quick status updates, confirmations, and [time-sensitive alerts](https://telnyx.com/use-cases/customer-notifications-system)
* **Voice call** for complex resolution, [urgent escalation](https://telnyx.com/use-cases/call-escalation), or the personal touch

The default demo scenario is a billing dispute: a customer disputes a $147.50 charge, and the agent emails an acknowledgment, texts a timeline confirmation, and calls only if the resolution needs one.

The same three tools fit any business. Point them at your own scenarios:

Travel app

Rebooking options by email after a cancelled flight, day-of alerts by SMS, a call when a change needs an immediate decision.

Restaurant app

Reservation confirmations by email, waitlist updates by SMS, a call when a table opens on short notice.

Appointments

Prep instructions by email a week out, a day-before reminder by SMS, a morning-of call if the customer hasn't confirmed.

A browser dashboard shows the agent's activity feed and channel timeline in real time, and the [full code is open source](https://github.com/team-telnyx/telnyx-code-examples/tree/main/omnichannel-ai-agent-python).

## What you need from the Telnyx Portal

Five things, and you likely have an account already if you build on Telnyx:

_The five Portal values the app needs._

| Item                                                          | Where in the Portal              | What the app uses it for                    |
| ------------------------------------------------------------- | -------------------------------- | ------------------------------------------- |
| **API key**                                                   | API Keys section                 | Authorizes inference, email, SMS, and calls |
| **[Phone number](https://telnyx.com/products/phone-numbers)** | Numbers section                  | From number for SMS and calls               |
| **Messaging Profile ID**                                      | Messaging section                | Routes outbound SMS                         |
| **Call Control Connection ID**                                | Voice, Call Control Applications | Places outbound calls                       |
| **Email sending address**                                     | Email section                    | From address for email                      |

A shared sending domain is available for testing, so you can send email before you verify your own domain.

Three pieces make it work:

1. **The brain**: [Telnyx Inference](https://telnyx.com/products/inference), an OpenAI-compatible API for open-source models. The default model is Llama 3.3 70B Instruct, and you can swap in any model Telnyx hosts with one environment variable.
2. **The channels**: the \[Email API\](<https://telnyx.com/products/email-api>, and [Voice API](https://telnyx.com/products/voice-api), all authorized by the same API key that powers inference.
3. **The memory**: SQLite, a simple local database, stores every message per customer with its channel, role, and timestamp. Every prompt the agent receives includes the full history.

## How the agent decides which channel to use

Three things govern every outreach the agent plans: the tools it can call, the channel guidance in its system prompt, and the conversation history it carries into each decision.

Tool calling sounds more technical than it is. The agent gets a small toolbox with four tools: `send_email`, `send_sms`, `make_call`, and `resolve_issue`. Each tool carries a short description that tells the agent when to reach for it. The SMS tool introduces itself like this:

JSON

123456

{ "name": "send\_sms", "description": "Send a short SMS text message to the customer. Use for quick status updates, confirmations, or time-sensitive notifications."}

The system prompt adds channel guidance, straight from `app.py`:

Text

123

\- Email: Formal acknowledgments, detailed explanations, records that need a paper trail\- SMS: Quick status updates, confirmations, time-sensitive alerts\- Voice call: Complex resolution, urgent escalation, personal touch for upset customers

For the demo's billing dispute, it even spells out the order of operations: email first to acknowledge the issue and outline next steps, SMS to confirm the email arrived with a timeline, and a call only if the resolution is complex.

**The rule of thumb in one line:** email keeps the record, SMS keeps the pace, a call keeps the customer. 

Then the agent works like anyone with a to-do list: read the situation, do the next right thing, check the result, repeat until the job is done. There is no script to follow and no timeline to hardcode. Each pass is one request to Telnyx Inference:

Python

12345

resp \= requests.post( "https://api.telnyx.com/v2/ai/chat/completions", headers\={"Authorization": f"Bearer {TELNYX\_API\_KEY}"}, json\={"model": AI\_MODEL, "messages": messages, "tools": TOOLS},)

The model looks at the scenario, the tools, and the conversation history, then decides its next move on its own. Every action comes back as a result it can react to, and it only stops when the issue is handled. The last move is always `resolve_issue`, with a short summary of what it did.

## How cross-channel memory works

Every message the agent sends or receives is stored with its channel:

Python

1234567

cur.execute( "INSERT INTO conversations " "(customer\_id, channel, role, content, timestamp) " "VALUES (?, ?, ?, ?, ?)", (customer\_id, channel, role, content, datetime.now(timezone.utc).isoformat()),)

Before the next run, the history is loaded and formatted into the prompt, so the model sees one timeline: what was emailed, what was texted, what was said on the call.

That memory is what separates an agent from three bots. The agent can say "as we emailed you this morning" in a text, and "following up on our email and text" on a call, and every line lands like it comes from one person. If the email and the SMS disagree, the customer notices, and every mismatch costs a little trust.

## Make it yours: a travel or restaurant example

The billing dispute is only the demo default. Swap the scenario text for your own business and the agent plans the channel mix. A [travel app](https://telnyx.com/solutions/travel-and-hospitality) handling a cancelled flight runs like this:

**A cancelled flight, as the agent works it**

| Step                              | Channel    | What the customer gets                                                                                                                                  |
| --------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1                                 | Email      | "We've rebooked your Oct 14 flight", with the new itinerary, fare difference, and a reference number.                                                   |
| 2, minutes later                  | SMS        | "Hi Sarah, we emailed you new options for your cancelled Oct 14 flight. Reply here if none of them work and we'll call you."                            |
| 3, if departure is under 24 hours | Voice call | "Hi Sarah, this is about your Oct 14 flight. We emailed rebooking options and texted you a summary. I'm calling to confirm which option works for you." |

Every message references the ones before it. The customer gets one coherent conversation across three channels.

**Other travel workflows, same pattern**

| Scenario           | Email                           | SMS                                   | Voice call                             |
| ------------------ | ------------------------------- | ------------------------------------- | -------------------------------------- |
| Pre-trip reminders | Prep instructions and documents | Day-before reminder                   | Morning-of confirmation if unanswered  |
| Itinerary change   | Updated booking details         | The one action the customer must take | If the change costs the customer money |

**A restaurant runs the same playbook**

| Scenario                     | Email                                         | SMS                                     | Voice call                                       |
| ---------------------------- | --------------------------------------------- | --------------------------------------- | ------------------------------------------------ |
| New reservation              | Booking confirmation with the guest's details | Day-of reminder with the address        | Only if the booking needs to change              |
| Large party, short on tables | The new arrangements in writing               | A quick heads-up that the seating moved | To apologize personally and confirm the new time |

The agent decides the mix. You write the scenario in plain language: "Customer's LHR to AMS flight on Oct 14 was cancelled." The agent plans the rest.

## Run it yourself

1. Clone the repo:

Bash

12

git clone https://github.com/team-telnyx/telnyx-code-examples.gitcd telnyx-code-examples/omnichannel-ai-agent-python

1. Install dependencies:

Bash

1

pip install \-r requirements.txt

1. Create your environment file:

Bash

1

cp .env.example .env

1. Fill in your API key, number, connection ID, and sending address:

Code

12345

TELNYX\_API\_KEY\=your\_telnyx\_api\_keyTELNYX\_FROM\_NUMBER\=+15551234567TELNYX\_EMAIL\_FROM\=agent@yourdomain.comCONNECTION\_ID\=your\_connection\_idAI\_MODEL\=meta-llama/Llama-3.3\-70B\-Instruct

1. Start the app and open the dashboard:

Bash

1

python app.py

The dashboard runs at `localhost:5000` with two panels: agent activity on the left, and the channel timeline on the right.

**Zero credentials needed.** Run `python demo/demo_server.py` and the entire flow is simulated, so you can watch the agent plan its outreach before you wire a single key. 

## Take it further

Right now the demo does the talking: it reaches out, but it doesn't listen for replies yet. Three upgrades turn it into something you can run for real customers:

1\. Let customers talk back

The code already knows how to receive a reply on all three channels (`message.received`, `email.received`, `call.answered`). Give it a public web address where Telnyx can deliver them, and the agent can listen, not just send.

2\. Try a different model

Change one line in your `.env` file to use any model in the [Telnyx Inference catalog](https://telnyx.com/llm-library). The rest of the app stays exactly the same.

3\. Plug in your CRM

The demo keeps its memory in a simple local database. Swap that part for your customer system, and every conversation lives where your team already works.

For the full pattern of handling replies, events, and status updates from every channel in one place, see [event-driven architecture for multi-channel communications](https://telnyx.com/resources/event-driven-communications-architecture?utm%5Fsource=telnyx%5Fblog&utm%5Fmedium=internal%5Flink&utm%5Fcampaign=202610%5FTOFU%5FOmnichannelAgent%5FTL%5FGLOBAL&utm%5Fcontent=how-to-build-an-omnichannel-ai-agent).

The same pattern works far beyond travel: [appointment reminders](https://telnyx.com/use-cases/automated-appointment-reminders), billing disputes, order updates, and renewal outreach all follow the same email, SMS, call pattern.

### Build your omnichannel agent on Telnyx

One API key for inference, email, SMS and voice, and one conversation memory across every channel.

[Start building](https://telnyx.com/sign-up?utm%5Fsource=telnyx%5Fblog&utm%5Fmedium=internal%5Flink&utm%5Fcampaign=202610%5FTOFU%5FOmnichannelAgent%5FTL%5FGLOBAL&utm%5Fcontent=how-to-build-an-omnichannel-ai-agent)

Share on Social

Deniz Yakisikli

Originally from Turkiye and living in Amsterdam, Deniz is a senior product marketing manager at Telnyx. She has her MBA in marketing management from the University of Amsterdam. Previously, she worked at the Coca-Cola Company, Vodafone, and Philips Health Systems. In her free tim

e, Deniz can be found traveling, practicing yoga, and scuba diving.

\[...\]

## Jump to:

[What is an omnichannel AI agent?](#what-is-an-omnichannel-ai-agent)[What you'll build](#what-youll-build)[What you need from the Telnyx Portal](#what-you-need-from-the-telnyx-portal)[How the agent decides which channel to use](#how-the-agent-decides-which-channel-to-use)[How cross-channel memory works](#how-cross-channel-memory-works)[Make it yours: a travel or restaurant example](#make-it-yours-a-travel-or-restaurant-example)[Run it yourself](#run-it-yourself)[Take it further](#take-it-further)

## Sign up for emails of our latest articles and news

[Start building](https://telnyx.com/sign-up)

### Ask AI

* [![GPT](https://d2efw2akbx8gaf.cloudfront.net/https://dotcom-payload-assets-prod.s3.us-east-1.amazonaws.com/cms-media/chatgpt_icon-ea55e09d.jpeg?width=92&format=webp)](https://chat.openai.com/?q=What makes Telnyx's global network different, breakdown call quality for normal phone calls and voice AI calls.)
* [![Claude](https://d2efw2akbx8gaf.cloudfront.net/https://dotcom-payload-assets-prod.s3.us-east-1.amazonaws.com/cms-media/claude_icon-c7c8eef3.webp?width=92&format=webp)](https://claude.ai/new?q=What makes Telnyx's global network different, breakdown call quality for normal phone calls and voice AI calls.)
* [![Perplexity](https://d2efw2akbx8gaf.cloudfront.net/https://dotcom-payload-assets-prod.s3.us-east-1.amazonaws.com/cms-media/perplexity_icon-cd5b74f1.webp?width=92&format=webp)](https://www.perplexity.ai/search?q=What makes Telnyx's global network different, breakdown call quality for normal phone calls and voice AI calls.)
* [![Gemini](https://d2efw2akbx8gaf.cloudfront.net/https://dotcom-payload-assets-prod.s3.us-east-1.amazonaws.com/cms-media/gemini_icon-4ff1cbf4.webp?width=92&format=webp)](https://www.google.com/search?udm=50&aep=11&q=What makes Telnyx's global network different, breakdown call quality for normal phone calls and voice AI calls.)
* [![Grok](https://d2efw2akbx8gaf.cloudfront.net/https://dotcom-payload-assets-prod.s3.us-east-1.amazonaws.com/cms-media/grok_icon-e588e5bd.webp?width=92&format=webp)](https://x.com/i/grok?text=What makes Telnyx's global network different, breakdown call quality for normal phone calls and voice AI calls.)