cd /news/developer-tools/build-an-ai-outbound-call-campaign-w… · home topics developer-tools article
[ARTICLE · art-112423] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Build an AI Outbound Call Campaign with Python and Telnyx

Telnyx has released an open-source AI Call Campaign Orchestrator built with Python, Flask, Telnyx Call Control, the Telnyx Agent SDK, SQLite, and SMS. The tool provides a backend template for outbound call campaigns, handling queueing, rate limiting, webhook verification, result tracking, and SMS summaries. It exposes a simple API for starting campaigns and polling status, with code available on GitHub.

read3 min views2 publishedAug 26, 2026

Outbound call campaigns look simple until you need them to behave like real software.

Calling one number is easy. Calling a list of numbers means you suddenly care about queueing, rate limits, call state, webhook verification, result tracking, and summaries for the team.

I built a small example for that pattern: an AI Call Campaign Orchestrator using Python, Flask, Telnyx Call Control, the Telnyx Agent SDK, SQLite, and SMS.

Code: https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-call-campaign-orchestrator

The app exposes a simple API:

POST /campaign

starts a campaign from a list of phone numbersGET /campaign/<campaign_id>

returns campaign status and call resultsPOST /webhooks/call

receives Telnyx Call Control eventsGET /health

confirms the service is runningThe interesting part is what happens after you submit the campaign.

The CampaignAgent

queues the calls, applies a rate limit, places outbound calls through Call Control, stores results in SQLite, and sends an SMS summary when the campaign is complete.

POST /campaign
  -> queue calls
  -> rate-limit delivery
  -> place calls with Call Control
  -> receive signed webhooks
  -> store results in SQLite
  -> send SMS summary

You send a list of E.164 phone numbers to POST /campaign

:

curl -X POST http://localhost:5000/campaign \
  -H "Content-Type: application/json" \
  -d '{
    "phone_numbers": [
      "+15551234567",
      "+15557654321",
      "+15559876543"
    ]
  }'

The API returns a campaign ID:

{
  "campaign_id": "3f2c1a5e-8b7d-4e6f-9a0c-1d2e3f4a5b6c",
  "status": "started"
}

From there, the agent owns the campaign lifecycle.

Outbound communication workflows need pacing.

If you fire too many calls at once, you can create a bad user experience and run into carrier or operational limits. This sample uses CALL_RATE_LIMIT_PER_MINUTE

so campaign delivery is controlled from configuration instead of buried inside the call loop.

That makes the campaign behavior easier to tune without rewriting the app.

For each queued number, the app places an outbound Call Control call with the Telnyx Python SDK.

The app needs:

TELNYX_API_KEY

TELNYX_CONNECTION_ID

TELNYX_PHONE_NUMBER

TELNYX_WEBHOOK_URL

The webhook URL points back to the app, so call lifecycle events can update campaign state as calls are answered, completed, or fail.

The webhook endpoint uses telnyx.webhooks.unwrap()

with the Telnyx Ed25519 public key.

That matters because webhook handlers should not blindly trust incoming HTTP requests. The app verifies that the event really came from Telnyx before it updates call state.

Telnyx Call Control event
  -> POST /webhooks/call
  -> verify signature
  -> update campaign result

At any point, you can poll:

curl http://localhost:5000/campaign/<campaign_id>

The response includes total calls, completion status, and per-number results.

That gives you a simple campaign dashboard API without adding another database service just for the sample.

When the campaign finishes, the app sends a summary SMS using Telnyx Messaging.

You configure:

TELNYX_SMS_FROM

TELNYX_SMS_TO

For a demo, this is a clean way to prove the workflow completed. In a production version, the same step could also notify Slack, update a CRM, or send a report to another internal system.

The app is not trying to be a full campaign product.

It is showing the backend shape you need for one:

That is the useful part. It gives you the skeleton for a durable communications workflow without starting from a pile of disconnected services.

Clone the repo:

git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/ai-call-campaign-orchestrator

Create a virtual environment and install dependencies:

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Configure your environment:

cp .env.example .env

Then fill in your Telnyx API key, connection ID, phone number, webhook URL, public key, SMS settings, and call rate limit.

Run the app:

python app.py

Resources:

── more in #developer-tools 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/build-an-ai-outbound…] indexed:0 read:3min 2026-08-26 ·