A phone number can tell you more than whether a lead typed ten valid digits into a form.
It can help you understand whether the number is valid, what carrier it belongs to, whether it is mobile or VoIP, what country it maps to, and whether the lead should probably be routed to SMS, voice, email, or a review queue.
The number-lookup-lead-enrichment-python example shows how to build that workflow with Telnyx Number Lookup and Telnyx AI Inference.
It is a small Flask app that accepts a lead phone number, looks up carrier and caller data through Telnyx, then asks a Telnyx-hosted model to score the lead and recommend a follow-up channel.
What the Example Builds
The app exposes three routes:
POST /enrich- enrich and score one lead phone numberPOST /enrich/bulk- enrich up to 50 phone numbersGET /health- check app health
It uses two Telnyx APIs:
GET /v2/number_lookup/{phone}
POST /v2/ai/chat/completions
The current default model in .env.example is:
AI_MODEL=MiniMaxAI/MiniMax-M3-MXFP8
The output is designed to be useful to an application, not just a person reading prose. The app returns phone enrichment fields and, when scoring succeeds, structured lead-quality data.
Why Lead Enrichment Is a Good AI App Pattern
Sales and growth workflows often start with incomplete data.
A lead fills out a form. You get a name, maybe an email address, maybe a phone number, and some free-text context. Before routing that lead, you may want to know:
- Is the phone number valid?
- Is it mobile, fixed line, VoIP, or something else?
- What carrier is associated with it?
- Does the caller name add useful context?
- Should this lead get SMS, voice, email, or manual review?
Number Lookup handles the phone intelligence. AI Inference handles the reasoning layer on top of that data.
That combination is useful because the enrichment output can feed a CRM, lead-routing system, sales dashboard, outbound campaign, or account qualification workflow.
Running the Example
Clone the examples repo and enter the project folder:
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/number-lookup-lead-enrichment-python
Create your environment file:
cp .env.example .env
Set your Telnyx API key:
TELNYX_API_KEY=your_telnyx_api_key
AI_MODEL=MiniMaxAI/MiniMax-M3-MXFP8
HOST=127.0.0.1
Install dependencies and run the app:
pip install -r requirements.txt
python app.py
The app starts locally on http://localhost:5000.
Enrich One Lead
Send a phone number to /enrich:
curl -X POST http://localhost:5000/enrich \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+12125550123"
}'
The app first calls Telnyx Number Lookup:
https://api.telnyx.com/v2/number_lookup/{phone}
Then it shapes the lookup response into enrichment data:
{
"phone": "+12125550123",
"carrier_name": "Example Carrier",
"carrier_type": "mobile",
"caller_name": "Example Name",
"line_type": "mobile",
"country": "US",
"valid_number": true
}
Next, the app sends that enrichment context to Telnyx AI Inference and asks for JSON with this shape:
{
"lead_quality": "hot",
"reasoning": "Valid mobile number with usable carrier data",
"is_mobile": true,
"is_voip": false,
"recommended_channel": "sms"
}
The final response includes the phone lookup fields and a score object when AI scoring succeeds.
The Inference Step
The inference prompt is intentionally constrained:
Score this lead based on phone data. Return only JSON, no prose, no markdown fences: lead_quality (hot/warm/cold), reasoning (string), is_mobile (boolean), is_voip (boolean), recommended_channel (sms/voice/email).
That shape matters. A sales workflow usually does not need a long explanation. It needs structured data that can be routed:
- Hot mobile leads can go into an SMS-first workflow
- Voice-ready leads can be routed to call queues
- VoIP or invalid-looking leads can be marked for review
- Cold leads can go into lower-priority nurture flows
The app also includes a small JSON parsing helper that strips markdown fences if needed and extracts the JSON object before parsing. That is a practical habit for production AI apps, even when the prompt asks for JSON only.
Bulk Enrichment
The bulk endpoint accepts up to 50 phone numbers:
curl -X POST http://localhost:5000/enrich/bulk \
-H "Content-Type: application/json" \
-d '{
"phone_numbers": [
"+12125550123",
"+14155550123"
]
}'
The response includes lookup results for each number:
{
"results": [
{
"phone": "+12125550123",
"carrier": "Example Carrier",
"type": "mobile",
"country": "US",
"valid": true
}
],
"total": 1
}
The sample keeps bulk enrichment simple. In production, you could add scoring, queue processing, rate limits, retries, and CRM updates.
Making It Production-Ready
This sample keeps state in memory and focuses on the workflow. For production, you would likely add:
- Persistent storage for enriched leads
- Authentication on the API routes
- Input validation and E.164 normalization
- Retry handling for lookup and inference calls
- Rate limiting for bulk enrichment
- CRM or marketing automation integration
- Human review for ambiguous or high-value leads
- Observability around lookup success, scoring success, and routing outcomes
The repo is intentionally agent-readable. The README, API reference, guide, environment template, and app code are structured so coding agents can inspect the project and help extend it. You can ask an agent to add CRM writes, stricter schema validation, retries, tests, or a scheduled enrichment job.