# Landline vs mobile: telling them apart before you dial or text

_2026-07-18 · Boundstone (https://boundstone.io/blog/landline-vs-mobile-lookup)_


You want texts to reach phones that can actually receive texts, and calls to land where someone picks up a handset. That means routing SMS to mobiles and voice to landlines, which means knowing — per number, before you spend anything — which is which. The good news: a lot of that split is already encoded in the number itself, and you can read it ahead of the dial or the send. The honest news: not all of it, and the gap is wider in North America than almost anywhere else.

## What line_type actually tells you

`POST /v1/verify/phone` returns a `line_type` field drawn from Google's libphonenumber metadata — the number's designated type in its national numbering plan. Values you will see include `mobile`, `fixed_line`, `voip`, `toll_free`, `premium_rate`, and `fixed_line_or_mobile`.

Read "designated type" literally. It is what the numbering plan says a range is for, not a live check that the specific number is a cell sitting in someone's pocket right now.

```bash
curl -X POST https://api.boundstone.io/v1/verify/phone \
  -H "Authorization: Bearer bs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+16504472983"}'
```

```json
{
  "valid": true,
  "e164": "+16504472983",
  "country": "US",
  "line_type": "fixed_line_or_mobile",
  "national_format": "(650) 447-2983",
  "checks": {
    "performed": ["format", "region", "line_type_metadata"],
    "not_performed": ["carrier_lookup", "ported_status", "hlr_liveness"]
  }
}
```

Every response carries that `checks` block — what we performed, and what we did not. It is the whole point: you never have to guess how the answer was derived.

## Where the plan lets you split them — and where it doesn't

In much of the world, numbering plans reserve separate ranges for mobile and fixed lines. UK mobiles begin `07`, so libphonenumber returns `mobile` cleanly; a London landline comes back `fixed_line`. The metadata partitions the two because the plan does.

North America is the hard case. The NANP shares ranges between cell and landline — the same area code plus prefix block can hold both. So US and Canadian numbers frequently return `fixed_line_or_mobile`. That value is not a hedge or a bug. It is the plan telling you it genuinely does not separate the two. When you see `fixed_line_or_mobile`, do not quietly file it under "mobile" because you would like it to be one — the metadata has no basis to pick, so neither should you.

Resolving it for real — is *this* US number a cell or a landline today — needs a live carrier lookup against the number's current operator. Boundstone does not run that by default. You can see it sitting in `not_performed` as `carrier_lookup` and `hlr_liveness`. It is a paid opt-in: send `hlr:true` and it runs for 5 credits, refunded if the network cannot answer. For a deeper look at the field, see [what phone line type actually means](/blog/what-is-phone-line-type).

## How to check one number

Interactive: drop a number into the [phone validator](/tools/phone-validator) and read the `line_type` alongside the checks block. Programmatic: the curl above. Either way, one number costs one credit — and the free tier is 250 credits a month, no card, and they never expire.

## How to segment a whole list

For a list, use bulk. Send a CSV with a single phone column as the raw request body:

```csv
phone
+16504472983
+442071838750
+61491570156
```

```bash
curl -X POST https://api.boundstone.io/v1/bulk/phone \
  -H "Authorization: Bearer bs_live_YOUR_KEY" \
  --data-binary @phones.csv
```

You get back HTTP 202 and a `job_id`; results land at `/v1/bulk/:id/results.csv`. One credit is reserved per row and refunded for any row that errors, so malformed lines do not cost you. Free jobs take 250 rows, paid jobs up to 10k. No appetite for curl? The dashboard has a CSV upload and paste box that runs the same thing.

Then segment on the results:

- Route `mobile` rows to SMS.
- Route `fixed_line` rows to your dialer.
- **Treat `fixed_line_or_mobile` as its own bucket.** Texting it is a gamble, so either call it instead or enrich it with a live carrier lookup before you send.

That third bucket is the discipline the whole exercise buys you. Metadata segments confidently where the plan allows and hands you a clearly labeled "we can't tell" pile where it doesn't, instead of a confident wrong answer.

## What "valid" does not mean

`valid: true` means the number is well-formed and possible for its region and carries the `line_type` its plan designates. It does **not** mean the number is currently in service, reachable, answered, or still with the carrier the range implies. A long-disconnected line can be perfectly valid.

VoIP is its own trap. `line_type` catches `voip` only for ranges *designated* for VoIP. A hosted or ported VoIP number that reuses an ordinary mobile or fixed range looks like a plain mobile or landline to metadata — invisible until a live carrier lookup says otherwise. That mechanism is covered in [how VoIP detection works and where it stops](/blog/detect-voip-phone-numbers).

One boundary worth stating plainly: none of this is DNC scrubbing or TCPA compliance. Segmenting by line type is list hygiene, not legal clearance. For Do-Not-Call and TCPA you need the official registries and your counsel. Boundstone is the hygiene layer, not the compliance layer. This is not legal advice.

## The short version

- **`line_type` is metadata, not a network check.** It reads the number's designated type from libphonenumber.
- **Most of the world splits cleanly.** Where numbering plans separate mobile and fixed ranges, you get a clean `mobile` / `fixed_line` split.
- **North America is the hard case.** Shared ranges mean you will often get `fixed_line_or_mobile` — honest abstention, not a guess. Resolving it needs a live `carrier_lookup`, which sits in `not_performed` unless you send `hlr:true`.
- **Segment lists with bulk CSV:** `mobile` to SMS, `fixed_line` to calls, ambiguous to its own deliberate bucket.
- **`valid` is not live, reachable or DNC-clean.** Hygiene, not compliance.

One free number away: [the phone validator](/tools/phone-validator) — 250 credits a month, no card.
