| name | omnichannel-context-carrying |
|---|---|
| title | Omnichannel Context-Carrying Agent |
| description | AI agent that carries customer context across email, voice, and SMS so customers never repeat themselves. Demonstrates cross-channel identity resolution with Telnyx Inference, Email, Messaging, and Call Control APIs. |
| language | python |
| framework | flask |
| telnyx_products | |
| channel |
| Email | Messaging | Voice | Call Control | AI Inference |
| email | sms | voice |
AI agent that carries customer context across email, voice, and SMS so customers never repeat themselves. When a customer calls after emailing, the AI greets them with: "I see you contacted us about changing your booking. Are you calling about the same request?"
Telnyx is an AI Communications Infrastructure platform — email, messaging, voice, and AI on one private, global network. This sample uses four Telnyx APIs (Email, Messaging, Call Control, AI Inference) from a single API key to demonstrate seamless cross-channel context carrying with customer identity resolution.
- Send Email :
POST /v2/emails—API reference - Send Message :
POST /v2/messages—API reference - Create Call :
POST /v2/calls—API reference - Answer Call :
POST /v2/calls/{call_control_id}/actions/answer—API reference - Speak :
POST /v2/calls/{call_control_id}/actions/speak—API reference - Gather Speech :
POST /v2/calls/{call_control_id}/actions/gather—API reference - AI Inference :
POST /v2/ai/chat/completions—API reference
This app handles these webhook events:
email.received— Inbound email triggers AI reply flowcall.initiated— Incoming call triggers identity lookup and answercall.answered— AI generates contextual greeting from cross-channel historycall.speak.ended— TTS playback finished, begins speech gatheringcall.gather.ended— Customer speech captured, AI processes with full contextcall.hangup— Call endedmessage.received— Inbound SMS triggers AI reply with cross-channel context
Customer contacts on any channel
│ │ │
Email in Call in SMS in
│ │ │
▼ ▼ ▼
┌─────────────────────────────┐
│ Flask app.py │
│ │
│ ┌───────────────────────┐ │
│ │ Customer Identity │ │
│ │ Registry (SQLite) │ │
│ │ email ↔ phone ↔ id │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ Cross-Channel │ │
│ │ Context Store │ │
│ │ (SQLite) │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ Telnyx AI Inference │ │
│ │ (context-aware │ │
│ │ greeting + reply) │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌────────┼────────┐ │
│ │ │ │ │
│ Email API SMS API Voice │
└─────────────────────────────┘
│ │ │
▼ ▼ ▼
Customer receives contextual
responses on every channel
The key differentiator: when a customer switches channels (e.g., emails then calls), the AI resolves their identity, loads the full cross-channel conversation history, and generates a greeting that references their prior interaction — so they never have to repeat themselves.
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 |
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 |
AI_MODEL |
string |
meta-llama/Llama-3.3-70B-Instruct |
no | Telnyx Inference model | Models |
PORT |
integer |
5000 |
no | HTTP server port | — |
DB_PATH |
string |
conversations.db |
no | SQLite database path | — |
Agent / CLI access — provision the resources above via the Telnyx CLI:
telnyx auth login
telnyx available-phone-numbers list --country US --features sms,voice
telnyx number-orders create --phone-number +15551234567
telnyx messaging-profiles create --name "Context Carrying Agent"
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/omnichannel-context-carrying-python
pip install -r requirements.txt
python demo/demo_server.py
The demo walks through "Sarah's Booking Change" — she emails about rescheduling, then calls and hears the AI greet her with full context from her email. No Telnyx credentials required.
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/omnichannel-context-carrying-python
cp .env.example .env # ← fill in your credentials
pip install -r requirements.txt
python app.py # starts on http://localhost:5000
Register a customer and test the flow:
curl -X POST http://localhost:5000/customers/register \
-H "Content-Type: application/json" \
-d '{
"id": "cust_sarah_chen",
"name": "Sarah Chen",
"email": "sarah@example.com",
"phone": "+15551234567"
}'
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
Register a customer identity for cross-channel resolution.
curl -X POST http://localhost:5000/customers/register \
-H "Content-Type: application/json" \
-d '{"id": "cust_001", "name": "Sarah Chen", "email": "sarah@example.com", "phone": "+15551234567"}'
List all registered customers.
curl http://localhost:5000/customers
View cross-channel context for a customer.
curl http://localhost:5000/customers/cust_001/context
View all cross-channel conversation history, grouped by customer.
curl http://localhost:5000/conversations
Trigger the full scripted demo journey (demo server only).
curl -X POST http://localhost:5555/demo/journey
Health check endpoint.
curl http://localhost:5000/health
Receives Telnyx Email webhook events. On email.received: resolves customer identity by email, stores the message, and triggers AI-generated reply in a background thread.
Receives Telnyx Call Control webhook events. On call.initiated (incoming): resolves customer by phone and answers. On call.answered: loads cross-channel history and generates a contextual greeting. On call.gather.ended: processes customer speech with full context.
Receives Telnyx Messaging webhook events. On message.received (inbound): resolves customer by phone, stores message, and triggers AI reply with cross-channel context.
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 |
| No contextual greeting | Customer not registered | Register the customer with matching email/phone via POST /customers/register |
| Webhook not received | Server not publicly reachable | Expose with ngrok and set webhook URLs in Portal |
| Unknown customer on inbound | Email/phone not in registry | Ensure the customer's email/phone matches their registration |
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