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 endpointsgit 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:
# Look up a number with POST
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 dataBuild carrier, line type, and portability checks into your app with Telnyx. Review the API reference, then send your first lookup request.
Start with Number LookupRelated articles