---
title: "What a phone number's line type tells you"
url: "https://lookvalid.com/blog/technical/mobile-landline-and-voip-line-types.md"
canonical_url: "https://lookvalid.com/blog/technical/mobile-landline-and-voip-line-types"
last_updated: "2026-10-22"
type: "conceptual"
summary: "Mobile, fixed line, VoIP, toll-free, premium and more: what each line type means, why some countries cannot separate them, and how porting limits a prefix."
related: ["https://lookvalid.com/tools/phone-number-validator.md", "https://lookvalid.com/tools/carrier-lookup.md", "https://lookvalid.com/docs.md", "https://lookvalid.com/blog/tutorial/validate-phone-numbers-python-api.md"]
---

# What a phone number's line type tells you

Mobile, fixed line, VoIP, toll-free, premium and more: what each line type means, why some countries cannot separate them, and how porting limits a prefix.

A line type sorts a phone number into a class such as mobile, fixed line or VoIP, and it decides whether you can text it, what a call to it costs, and how much to trust it as a contact. The label comes from the numbering plan, which records what a range of numbers was set aside for, so it has limits. This post explains the types, why some countries cannot separate mobile from fixed, why a prefix does not name today's carrier, and how to use the fields our phone and carrier lookup products return.

## Where a line type comes from

Every number sits in a range that the national regulator assigned for one kind of service. A tool that reads those ranges can tell you what the range is for. The phone product uses Google's libphonenumber metadata through the `libphonenumber-js` package, and it returns the result in a field called `number_type` next to a `line_type_source` field that always reads `numbering-plan` [1].

The library documents the types it can return: `MOBILE`, `FIXED_LINE`, `FIXED_LINE_OR_MOBILE`, `PREMIUM_RATE`, `TOLL_FREE`, `SHARED_COST`, `VOIP`, `PERSONAL_NUMBER`, `PAGER` and `UAN` [1]. Our output uses the same list in lowercase with underscores, plus `unknown` for a valid number whose range has no type in the metadata.

Nothing here contacts a carrier. The result is a statement about the range, so it cannot say whether a number is switched on or which network serves it today.

## The line types and what to do with each

Line types the phone product can return

| number_type | Plain meaning | Practical implication |
| --- | --- | --- |
| mobile | A cellphone range [1] | Safe to send an SMS to, subject to your own sending rules |
| fixed_line | A stationary phone range [1] | Voice only in most cases, so do not send a text-only verification code |
| fixed_line_or_mobile | The range could be either [1] | Treat as unknown for SMS and test with a real message or a carrier check |
| voip | Calls carried over the internet rather than conventional lines [1] | Not tied to a SIM or a street address, so weigh it in your own risk scoring but do not reject it on type alone |
| toll_free | Free to call from anywhere [1] | Free to call, so it is usually a service line: check before storing it as a personal contact |
| premium_rate | The caller is charged by call or per minute, and texts can be charged too [1] | Never call back or text automatically; flag as a data-entry error in most forms |
| shared_cost | The recipient pays part of the call charge [1] | The caller may pay more than for a normal call: check before auto-dialling |
| personal_number | A special range the library describes as phones connected by satellites [1] | Rare; route to review rather than assuming a reachable person |
| pager | A paging service range [1] | Not a voice contact; treat as unusable for outreach |
| uan | A universal access number that reaches a service with several lines [1] | A switchboard, not a person |
| unknown | Valid number, but the metadata gives its range no type | Do not guess; fall back to your default handling |

The library also warns against storing a number's type: a number can be disconnected tomorrow, and the phone company may change the range that a type applies to, so check the type again when you need it [2].

## Real output on fictional numbers

We ran the phone provider from our repository on a set of fictional example numbers. None is a number we know to belong to anyone. These are the results as returned, with the country the provider reported.

number_type and country returned by the phone provider

| Input (E.164) | number_type | country |
| --- | --- | --- |
| +12025550143 | fixed_line_or_mobile | US (area code region: District of Columbia) |
| +14155550123 | fixed_line_or_mobile | US |
| +18005550123 | toll_free | US |
| +19005550123 | premium_rate | US |
| +15005550006 | personal_number | US |
| +442079460123 | fixed_line | GB |
| +441134960123 | fixed_line | GB |
| +447400123456 | mobile | GB |
| +445612345678 | voip | GB |
| +448081570123 | toll_free | GB |
| +449098790123 | premium_rate | GB |
| +443069990123 | uan | GB |
| +447640123456 | pager | GB |
| +447911123456 | mobile | GG |
| +33612345678 | mobile | FR |
| +33810123456 | shared_cost | FR |
| +4915123456789 | mobile | DE |

Three things stand out. Every US number that is not toll-free, premium or personal came back as `fixed_line_or_mobile`, while the UK, France and Germany numbers came back as plainly mobile or fixed. A number that begins with the UK code, +44, can report Guernsey (`GG`) as its country. And a number that fits a country's length rules but sits in no assigned range, such as +6125550100, is not a match: the provider returns a free `not_found` with the reason instead of a guess.

## Why some countries cannot separate mobile from fixed

The combined type is not a bug. In the US and Canada the metadata has no range that separates cellphones from stationary phones, so a US number gets `fixed_line_or_mobile`, as the table shows. The library describes that type as one that "could be MOBILE or FIXED_LINE" [1].

The library notes that geographic area codes are assigned to mobile phones in some countries, so an area code is not proof of a landline either [2]. For a decision that depends on the answer, such as whether to send an SMS, treat the combined type as a prompt to verify, not as permission.

## Why a prefix names the original range, not today's carrier

Where number portability exists, a person can keep a number when switching providers. US federal rules define number portability as the ability to retain existing numbers at the same location without impairment of quality, reliability or convenience when switching from one carrier to another [3]. The library says the same in practice: in countries with portability you may keep your number when moving, even in some cases a fixed-line number [2].

So a prefix tells you who the range was first handed to. The carrier lookup product is built on that fact. It reads the public North American numbering reports and returns `original_carrier`, with `ported` fixed at `unknown` and a note that a number moved to another carrier still shows its original one. Use it to understand where a block started, not to route a call.

- Use the `phone` product when you need the type and the E.164 form. It covers every country the library supports.
- Use `carrier-lookup` when you need the original carrier of a North American number. Numbers outside the North American plan return a free not-found.
- Neither one tells you if a number is active, ported or reachable.

## Using line_type in your code

The two products name the field differently. The phone product returns `number_type` with the full list above. The carrier lookup returns `line_type`, which is only `mobile` or `unknown`, and its `line_type_basis` field says it comes from keywords in the carrier name (such as wireless or cellular), not from an official category. Treat `unknown` there as "no hint", never as "landline". A phone lookup is 1 credit for a valid number, and a number the numbering plan rejects costs nothing.

Look up one number

```bash
curl -X POST https://YOUR_API_HOST/v1/phone \
  -H "Authorization: Bearer $LOOKVALID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+442079460123"}'
```

Decide what to do with the number type

```ts
type NumberType =
  | 'mobile' | 'fixed_line' | 'fixed_line_or_mobile' | 'voip' | 'toll_free'
  | 'premium_rate' | 'shared_cost' | 'personal_number' | 'pager' | 'uan' | 'unknown';

function smsPolicy(type: NumberType): 'send' | 'verify_first' | 'skip' {
  if (type === 'mobile') return 'send';
  if (type === 'fixed_line_or_mobile' || type === 'voip' || type === 'unknown') return 'verify_first';
  return 'skip';
}
```

Try a number in the [phone number validator](https://lookvalid.com/tools/phone-number-validator.md) or the [carrier lookup](https://lookvalid.com/tools/carrier-lookup.md), read the [API docs](https://lookvalid.com/docs.md), or follow the [Python tutorial](https://lookvalid.com/blog/tutorial/validate-phone-numbers-python-api.md) to check a whole list.

## Sources

1. [libphonenumber-js README: phone number types](https://gitlab.com/catamphetamine/libphonenumber-js/-/blob/master/README.md), read 2026-10-19
2. [Google libphonenumber: Falsehoods programmers believe about phone numbers](https://github.com/google/libphonenumber/blob/master/FALSEHOODS.md), read 2026-10-19
3. [47 CFR 52.21: Definitions (number portability)](https://www.law.cornell.edu/cfr/text/47/52.21), read 2026-10-19

By LookValid data team. Published 2026-10-19, updated 2026-10-19.

## Related

- [Free phone number validator](https://lookvalid.com/tools/phone-number-validator.md)
- [Free carrier lookup](https://lookvalid.com/tools/carrier-lookup.md)
- [Documentation](https://lookvalid.com/docs.md)
- [Validate a list of phone numbers with Python](https://lookvalid.com/blog/tutorial/validate-phone-numbers-python-api.md)
