cd /news/developer-tools/phone-number-carrier-and-line-type-w… · home topics developer-tools article
[ARTICLE · art-46448] src=telnyx.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Phone Number Carrier and Line Type with Python and the Telnyx Number Lookup

Telnyx launched a Number Lookup API that returns carrier, line type, and portability data for any phone number in a single request, and released a Python Flask example with a 24-hour in-memory cache. The tool helps developers automate call routing, SMS deliverability checks, and lead enrichment by integrating carrier data directly into applications.

read5 min views1 publishedJul 1, 2026
Phone Number Carrier and Line Type with Python and the Telnyx Number Lookup
Image: source

Contact us

Log in

A phone number carrier lookup identifies the current network operator, line type, number type, and portability status tied to a phone number. Developers use it to decide whether a number can receive SMS, whether a call should route to an agent, and whether contact data is current before the first message or call goes out.

The Telnyx Number Lookup API returns carrier, line type, and portability data for any phone number in a single request, using Telnyx carrier network data rather than only a third-party reseller feed. This walkthrough builds a Python Flask service that wraps that API with a 24-hour in-memory cache so repeat lookups are fast and do not create repeat API calls during the TTL.

The full code is available in the Telnyx code examples repo: phone-number-lookup-python.

The Flask app exposes three endpoints:

Method Path Purpose
POST /lookup Look up a number from a JSON body
GET /lookup/<phone_number> Look up a number from the URL path
GET /cache/stats Inspect the in-memory cache

When a lookup request arrives, the app checks the cache first. On a cache miss, it calls the Telnyx Number Lookup API, extracts carrier name, carrier type, line type, number type, and portability status, then returns a clean JSON response. Cached responses include from_cache

set to true

.

Number Lookup is a single API call: GET /v2/number_lookup/{phone_number}

. There are no webhooks, no long-running jobs, and no polling. For endpoint details, see the Number Lookup guide.

+15551234567

. The example rejects numbers that do not start with +

. Number lookup is not a standalone task. It is a building block for routing, trust, deliverability, and lead quality.

Check carrier and line type before connecting a caller to an agent. If you route calls with Telnyx Voice API, lookup results can feed programmable call routing before a caller reaches a queue.

Sales teams can tell whether a prospect has a mobile line, landline, or disposable VoIP number. Teams that manage inventory through Telnyx Phone Numbers can search, buy, and manage numbers in one place.

Landlines usually cannot receive SMS. With Telnyx SMS API, lookup results can keep text workflows focused on mobile-capable numbers.

A number that was recently ported may point to a carrier change. That matters for compliance checks, deliverability, and customer data freshness.

Free web tools are useful for one-off checks, but they usually require manual input and do not fit automated call routing, lead enrichment, or fraud screening. An API approach works inside your application, where lookup results can be cached, logged, monitored, and used in routing decisions.

Free lookup tools Telnyx Number Lookup API Twilio Lookup
Data source: Often public or reseller data shown on a manual web page. Data source: Telnyx carrier network data returned through API fields. Data source: Provider lookup data returned through Twilio endpoints.
API access: Usually limited or unavailable. API access: Yes, with carrier, line type, number type, and portability fields. API access: Yes, through Twilio Lookup.
Cache support: Manual tools do not manage your app cache. Cache support: Add app-side cache logic, as shown in this Flask example. Cache support: Add app-side cache logic based on your workflow.
Integration: Best for a single manual check. Integration: Best for Python services, routing systems, lead enrichment, and fraud checks. Integration: Best for teams already building around Twilio.

This example uses a simple request, cache, API, response pattern. A cache hit returns local JSON. A cache miss calls Telnyx, stores the result for 24 hours, and returns the same response shape to the client.

Telnyx Number Lookup pipeline

[Client request] | v [Flask /lookup endpoint] | v [Cache check] | hit | miss v v [Return cached JSON] [Telnyx Number Lookup API] | v [Store in 24h cache] | v [Return JSON response]

curl

or Postman to test the endpoints

git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/phone-number-lookup-python
cp .env.example .env
pip install -r requirements.txt

Edit .env

and set your API key:

TELNYX_API_KEY=KEY012...CDEF
FLASK_DEBUG=false

Start the server:

python app.py

The app runs on

.http://localhost:5000

The Telnyx Python SDK creates an authenticated client once at startup:

client = telnyx.Telnyx(api_key=os.getenv("TELNYX_API_KEY"))

The core function validates the phone number format, checks the cache, and calls Telnyx on a miss.

def lookup_phone_number(phone_number: str) -> dict:
    if not phone_number.startswith("+"):
        raise ValueError("Phone number must be in E.164 format (e.g., +15551234567)")
cached_result = get_cached_lookup(phone_number)
if cached_result:
    cached_result["from_cache"] = True
    return cached_result

response = client.number_lookup.retrieve(phone_number)

lookup_data = {
    "phone_number": response.data.phone_number,
    "country_code": response.data.country_code,
    "carrier": {
        "name": response.data.carrier.name if response.data.carrier else None,
        "type": response.data.carrier.type if response.data.carrier else None,
    },
    "line_type": response.data.line_type,
    "number_type": response.data.number_type,
    "portability": {
        "status": response.data.portability.status if response.data.portability else None,
        "last_checked_at": response.data.portability.last_checked_at if response.data.portability else None,
    },
    "from_cache": False,
}

cache_lookup_result(phone_number, lookup_data)
return lookup_data</code></pre>

The cache is a Python dict with a 24-hour TTL. Each entry stores the lookup result and a timestamp. is_cache_valid()

compares the stored timestamp against the TTL, and expired entries are replaced on the next lookup.

This keeps repeated lookups of the same number free of repeat API calls during the 24-hour window.

The Flask endpoints catch Telnyx SDK exceptions and return clear HTTP status codes:

curl -X POST http://localhost:5000/lookup \
  -H "Content-Type: application/json" \
  -d '{"phone_number": "+15551234567"}'

curl http://localhost:5000/lookup/+15551234567

curl http://localhost:5000/cache/stats

Run the same lookup twice. The second response returns from_cache

set to true

.

This example uses an in-memory cache for simplicity. For production, adapt the service around your traffic patterns and data retention needs.

number-lookup-fraud-screener-python

for screening inbound numbers before connectingnumber-lookup-lead-enrichment-python

for enriching sales leads with carrier and CNAM datacnam-caller-id-lookup-enrichment-python

for caller ID enrichmentbulk-number-validation-cleaner-python

for validating and cleaning lists of numbersStart looking up carrier data Build carrier, line type, and portability checks into your app with Telnyx. Review the API reference, then send your first lookup request.

Related articles

── 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/phone-number-carrier…] indexed:0 read:5min 2026-07-01 ·