| name | omnichannel-ai-agent |
|---|---|
| title | Omnichannel AI Agent |
| description | One AI agent that proactively emails, texts, and calls customers using Claude tool-calling, Telnyx Email/SMS/Voice APIs, and SQLite for persistent cross-channel context. |
| language | python |
| framework | flask |
| telnyx_products | |
| channel |
| Email | Messaging | Voice | Call Control |
| email | sms | voice |
One AI agent that proactively emails, texts, and calls customers. Claude API decides which channel to use via tool-calling. Telnyx handles Email, SMS, and Voice delivery. SQLite stores persistent cross-channel conversation context.
Telnyx is an AI Communications Infrastructure platform — email, messaging, voice, and AI on one private, global network. This sample uses three Telnyx APIs (Email, Messaging, Call Control) from a single API key, demonstrating unified omnichannel communication.
- Send Email :
POST /v2/email_messages—API reference - Send Message :
POST /v2/messages—API reference - Create Call :
POST /v2/calls—API reference - Speak :
POST /v2/calls/{call_control_id}/actions/speak—API reference - Hangup :
POST /v2/calls/{call_control_id}/actions/hangup—API reference
This app handles these webhook events:
call.answered— Call connected, app speaks the AI-generated messagecall.speak.ended— TTS playback finished, app hangs upcall.hangup— Call endedmessage.received— Inbound SMS reply from customeremail.received— Inbound email reply from customer
Claude API (AI Brain)
│
Tool-calling decides
which channel to use
│
┌────┴────┐
│ Flask │
│ app.py │
│ │
┌─────┤ Context ├─────┐
│ │ (SQLite)│ │
│ └────┬────┘ │
│ │ │
Email API Messaging Call Control
POST /v2/ POST /v2/ POST /v2/
email_messages messages calls
│ │ │
▼ ▼ ▼
Customer Customer Customer
inbox phone phone
The AI agent receives a customer scenario, retrieves the full cross-channel conversation history from SQLite, and uses Claude's tool-calling to decide the next action. Claude chooses email for formal acknowledgments, SMS for quick updates, and voice for complex resolution — each message references previous interactions across channels.
Copy .env.example to .env and fill in:
| Variable | Type | Example | Required | Description | Where to get it |
|---|---|---|---|---|---|
TELNYX_API_KEY |
string |
KEY0123456789ABCDEF |
yes | Telnyx API v2 key | Portal ·CLI: telnyx auth |
ANTHROPIC_API_KEY |
string |
sk-ant-api03-... |
yes | Claude API key | Anthropic Console |
TELNYX_FROM_NUMBER |
string |
+15551234567 |
yes | Telnyx phone number (SMS + Voice) | Portal |
TELNYX_EMAIL_FROM |
string |
agent@yourdomain.com |
yes | Verified sender email | Portal |
MESSAGING_PROFILE_ID |
string |
40017b7e-... |
no | Messaging profile ID | Portal |
CONNECTION_ID |
string |
1494404757140276705 |
yes | Call Control connection ID | Portal |
PORT |
integer |
5000 |
no | HTTP server port | — |
DB_PATH |
string |
conversations.db |
no | SQLite database path | — |
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/omnichannel-ai-agent-python
pip install -r requirements.txt
python demo/demo_server.py
The demo walks through a billing dispute scenario: the agent sends an email, follows up via SMS, then calls the customer — all with shared context. No Telnyx or Claude credentials required.
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/omnichannel-ai-agent-python
cp .env.example .env # ← fill in your credentials
pip install -r requirements.txt
python app.py # starts on http://localhost:5000
Trigger the agent:
curl -X POST http://localhost:5000/agent/run \
-H "Content-Type: application/json" \
-d '{
"customer": {
"id": "cust_001",
"name": "Sarah Chen",
"email": "sarah@example.com",
"phone": "+15551234567"
},
"scenario": "Customer is disputing a $147.50 charge on their September statement."
}'
Expose your local server:
ngrok http 5000
Copy the HTTPS URL and configure in Telnyx Portal :
- Call Control Application → Webhook URL →
https://<id>.ngrok.io/webhooks/voice - Messaging Profile → Inbound Webhook URL →
https://<id>.ngrok.io/webhooks/messaging - Email → Inbound Webhook URL →
https://<id>.ngrok.io/webhooks/email
Trigger the AI agent for a customer scenario.
curl -X POST http://localhost:5000/agent/run \
-H "Content-Type: application/json" \
-d '{"customer": {"id": "cust_001", "name": "Jane", "email": "jane@example.com", "phone": "+15551234567"}, "scenario": "Billing dispute"}'
Response:
{
"status": "completed",
"actions": [
{"type": "tool_call", "tool": "send_email", "input": {"subject": "...", "body": "..."}, "result": "Email sent..."},
{"type": "tool_call", "tool": "send_sms", "input": {"text": "..."}, "result": "SMS sent..."},
{"type": "tool_call", "tool": "make_call", "input": {"speak_text": "..."}, "result": "Call initiated..."}
]
}
View all cross-channel conversation history, grouped by customer.
curl http://localhost:5000/conversations
Health check endpoint.
curl http://localhost:5000/health
Receives Telnyx Call Control webhook events.
Events handled: call.answered, call.speak.ended, call.hangup
Receives Telnyx Messaging webhook events.
Events handled: message.received
Receives Telnyx Email webhook events.
Events handled: email.received
python -m pytest smoke_test.py -v
| Issue | Cause | Fix |
|---|---|---|
401 Unauthorized |
Invalid API key | Verify TELNYX_API_KEY in.env matches your key in thePortal |
| Email not sending | Sender not verified | Verify your email domain in the Telnyx Email Portal |
| Call not connecting | Invalid CONNECTION_ID | Verify your Call Control Application in the Portal |
| Claude API error | Invalid ANTHROPIC_API_KEY | Verify your key at console.anthropic.com |
| Webhook not received | Server not publicly reachable | Expose with ngrok and set webhook URLs in Portal |
This example is part of the Telnyx Code Examples catalog.
- Agent signup :telnyx.com/agent-signup.md — automated account provisioning via agent mail
- Agent CLI :github.com/team-telnyx/ai/tree/main/cli
- LLM-optimized docs :
llms-full.txt - Example index :
llms.txt