{"slug": "ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context", "title": "AI agent that emails, texts, and calls customers – one API, shared context", "summary": "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.", "body_md": "| name | omnichannel-ai-agent | \n|---|---|\n| title | Omnichannel AI Agent | \n| 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. | \n| language | python | \n| framework | flask | \n| telnyx_products |  | \n| channel |  | \n\n| Email | Messaging | Voice | Call Control | \n\n| email | sms | voice | \n\nOne 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.\n\nTelnyx 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.\n\n- **Send Email** :`POST /v2/email_messages` —[API reference](https://developers.telnyx.com/api/email/send-email)\n- **Send Message** :`POST /v2/messages` —[API reference](https://developers.telnyx.com/api/messaging/send-message)\n- **Create Call** :`POST /v2/calls` —[API reference](https://developers.telnyx.com/api/call-control/create-call)\n- **Speak** :`POST /v2/calls/{call_control_id}/actions/speak` —[API reference](https://developers.telnyx.com/api/call-control/speak)\n- **Hangup** :`POST /v2/calls/{call_control_id}/actions/hangup` —[API reference](https://developers.telnyx.com/api/call-control/hangup)\n\nThis app handles these webhook events:\n\n- `call.answered` — Call connected, app speaks the AI-generated message\n- `call.speak.ended` — TTS playback finished, app hangs up\n- `call.hangup` — Call ended\n- `message.received` — Inbound SMS reply from customer\n- `email.received` — Inbound email reply from customer\n\n```\n                    Claude API (AI Brain)\n                         │\n                    Tool-calling decides\n                    which channel to use\n                         │\n                    ┌────┴────┐\n                    │ Flask   │\n                    │ app.py  │\n                    │         │\n              ┌─────┤ Context ├─────┐\n              │     │ (SQLite)│     │\n              │     └────┬────┘     │\n              │          │          │\n         Email API   Messaging  Call Control\n        POST /v2/    POST /v2/   POST /v2/\n     email_messages  messages     calls\n              │          │          │\n              ▼          ▼          ▼\n           Customer   Customer   Customer\n           inbox      phone      phone\n```\n\nThe 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.\n\nCopy `.env.example` to `.env` and fill in:\n\n| Variable | Type | Example | Required | Description | Where to get it | \n|---|---|---|---|---|---|\n| `TELNYX_API_KEY` | `string` | `KEY0123456789ABCDEF` | **yes** | Telnyx API v2 key | [Portal](https://portal.telnyx.com/api-keys) ·[CLI: `telnyx auth`](https://developers.telnyx.com/development/cli) | \n| `ANTHROPIC_API_KEY` | `string` | `sk-ant-api03-...` | **yes** | Claude API key | [Anthropic Console](https://console.anthropic.com) | \n| `TELNYX_FROM_NUMBER` | `string` | `+15551234567` | **yes** | Telnyx phone number (SMS + Voice) | [Portal](https://portal.telnyx.com/numbers/my-numbers) | \n| `TELNYX_EMAIL_FROM` | `string` | `agent@yourdomain.com` | **yes** | Verified sender email | [Portal](https://portal.telnyx.com/email) | \n| `MESSAGING_PROFILE_ID` | `string` | `40017b7e-...` | no | Messaging profile ID | [Portal](https://portal.telnyx.com/messaging/profiles) | \n| `CONNECTION_ID` | `string` | `1494404757140276705` | **yes** | Call Control connection ID | [Portal](https://portal.telnyx.com/call-control/applications) | \n| `PORT` | `integer` | `5000` | no | HTTP server port | — | \n| `DB_PATH` | `string` | `conversations.db` | no | SQLite database path | — | \n\n```\ngit clone https://github.com/team-telnyx/telnyx-code-examples.git\ncd telnyx-code-examples/omnichannel-ai-agent-python\n\npip install -r requirements.txt\n\npython demo/demo_server.py\n```\n\nThe 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.\n\n```\ngit clone https://github.com/team-telnyx/telnyx-code-examples.git\ncd telnyx-code-examples/omnichannel-ai-agent-python\n\ncp .env.example .env    # ← fill in your credentials\npip install -r requirements.txt\npython app.py           # starts on http://localhost:5000\n```\n\nTrigger the agent:\n\n```\ncurl -X POST http://localhost:5000/agent/run \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"customer\": {\n      \"id\": \"cust_001\",\n      \"name\": \"Sarah Chen\",\n      \"email\": \"sarah@example.com\",\n      \"phone\": \"+15551234567\"\n    },\n    \"scenario\": \"Customer is disputing a $147.50 charge on their September statement.\"\n  }'\n```\n\n1. \nExpose your local server: \n\n```\nngrok http 5000\n```\n\n2. \nCopy the HTTPS URL and configure in [Telnyx Portal](https://portal.telnyx.com) :\n  - **Call Control Application** → Webhook URL →`https://<id>.ngrok.io/webhooks/voice`\n  - **Messaging Profile** → Inbound Webhook URL →`https://<id>.ngrok.io/webhooks/messaging`\n  - **Email** → Inbound Webhook URL →`https://<id>.ngrok.io/webhooks/email`\n\nTrigger the AI agent for a customer scenario.\n\n```\ncurl -X POST http://localhost:5000/agent/run \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"customer\": {\"id\": \"cust_001\", \"name\": \"Jane\", \"email\": \"jane@example.com\", \"phone\": \"+15551234567\"}, \"scenario\": \"Billing dispute\"}'\n```\n\n**Response:**\n\n```\n{\n  \"status\": \"completed\",\n  \"actions\": [\n    {\"type\": \"tool_call\", \"tool\": \"send_email\", \"input\": {\"subject\": \"...\", \"body\": \"...\"}, \"result\": \"Email sent...\"},\n    {\"type\": \"tool_call\", \"tool\": \"send_sms\", \"input\": {\"text\": \"...\"}, \"result\": \"SMS sent...\"},\n    {\"type\": \"tool_call\", \"tool\": \"make_call\", \"input\": {\"speak_text\": \"...\"}, \"result\": \"Call initiated...\"}\n  ]\n}\n```\n\nView all cross-channel conversation history, grouped by customer.\n\n```\ncurl http://localhost:5000/conversations\n```\n\nHealth check endpoint.\n\n```\ncurl http://localhost:5000/health\n```\n\nReceives [Telnyx Call Control](https://developers.telnyx.com/docs/voice/call-control) webhook events.\n\n**Events handled:** `call.answered`, `call.speak.ended`, `call.hangup`\n\nReceives [Telnyx Messaging](https://developers.telnyx.com/docs/messaging) webhook events.\n\n**Events handled:** `message.received`\n\nReceives Telnyx Email webhook events.\n\n**Events handled:** `email.received`\n\n```\npython -m pytest smoke_test.py -v\n```\n\n| Issue | Cause | Fix | \n|---|---|---|\n| `401 Unauthorized` | Invalid API key | Verify `TELNYX_API_KEY` in`.env` matches your key in the[Portal](https://portal.telnyx.com/api-keys) | \n| Email not sending | Sender not verified | Verify your email domain in the [Telnyx Email Portal](https://portal.telnyx.com/email) | \n| Call not connecting | Invalid CONNECTION_ID | Verify your Call Control Application in the [Portal](https://portal.telnyx.com/call-control/applications) | \n| Claude API error | Invalid ANTHROPIC_API_KEY | Verify your key at [console.anthropic.com](https://console.anthropic.com) | \n| Webhook not received | Server not publicly reachable | Expose with ngrok and set webhook URLs in Portal | \n\nThis example is part of the [Telnyx Code Examples](https://github.com/team-telnyx/telnyx-code-examples) catalog.\n\n- **Agent signup** :[telnyx.com/agent-signup.md](https://telnyx.com/agent-signup.md) — automated account provisioning via agent mail\n- **Agent CLI** :[github.com/team-telnyx/ai/tree/main/cli](https://github.com/team-telnyx/ai/tree/main/cli)\n- **LLM-optimized docs** :[`llms-full.txt`](https://developers.telnyx.com/llms-full.txt)\n- **Example index** :[`llms.txt`](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main/llms.txt)", "url": "https://wpnews.pro/news/ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context", "canonical_source": "https://github.com/team-telnyx/telnyx-code-examples/tree/main/omnichannel-ai-agent-python", "published_at": "2026-09-28 13:12:30+00:00", "updated_at": "2026-09-28 13:17:24.691956+00:00", "lang": "en", "topics": ["ai-agents", "ai-products", "developer-tools", "large-language-models"], "entities": ["Telnyx", "Claude", "Anthropic", "Flask", "SQLite", "Telnyx Email API", "Telnyx Messaging API", "Telnyx Call Control API"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context", "markdown": "https://wpnews.pro/news/ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context.md", "text": "https://wpnews.pro/news/ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context.txt", "jsonld": "https://wpnews.pro/news/ai-agent-that-emails-texts-and-calls-customers-one-api-shared-context.jsonld"}}