cd /news/ai-agents/ai-agent-that-emails-texts-and-calls… · home › topics › ai-agents › article
[ARTICLE · art-140988] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

AI agent that emails, texts, and calls customers – one API, shared context

Telnyx published an open-source Python sample, omnichannel-ai-agent, that lets a single Claude tool-calling agent proactively email, text, and call customers through three Telnyx APIs — Email (POST /v2/email_messages), Messaging (POST /v2/messages), and Call Control (POST /v2/calls) — using one TELNYX_API_KEY. The Flask app stores persistent cross-channel conversation context in SQLite and handles webhook events including call.answered, call.speak.ended, call.hangup, message.received, and email.received, with Claude selecting email for formal acknowledgments, SMS for quick updates, and voice for complex resolution. Setup requires TELNYX_API_KEY, ANTHROPIC_API_KEY, TELNYX_FROM_NUMBER, TELNYX_EMAIL_FROM, and CONNECTION_ID, with MESSAGING_PROFILE_ID optional.

read4 min views2 publishedSep 28, 2026
AI agent that emails, texts, and calls customers – one API, shared context
Image: Michielbdejong (auto-discovered)
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.

This app handles these webhook events:

  • call.answered — Call connected, app speaks the AI-generated message
  • call.speak.ended — TTS playback finished, app hangs up
  • call.hangup — Call ended
  • message.received — Inbound SMS reply from customer
  • email.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.

── more in #ai-agents 4 stories · sorted by recency
── more on @telnyx 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/ai-agent-that-emails…] indexed:0 read:4min 2026-09-28 · —