Skip to main content
Back to blog

Phone-Number Lookup and SIM-Swap Pre-Send — a CPaaS Buyer Guide

The number-lookup problem in plain words — validity, reachability, and the SIM-swap check that fires before you send. This buyer guide walks Devotel Orbit's Lookup surface (single dip, Twilio-compatible data packages, 100-number bulk scrub), the three acceptance patterns that map to real flows, and the billing rules that keep the economics predictable.

Orbit Editorial Team

Every CPaaS shortlist credits someone with "number lookup" — the comparison pages never tell you what is actually being looked up, or what the check is worth if it fires after the message already sent. This guide fills that gap. It names the three questions lookup answers (is the number valid, is it reachable right now, and was the SIM changed just before your OTP sends), walks the product surface Devotel Orbit exposes for each, and gives you the acceptance patterns and billing rules to evaluate a lookup vendor on — not an opinion, a checklist.

The number-lookup problem, defined precisely

Lookup is three distinct problems, and a vendor page that answers one while implying all three is the most common buyer trap:

  1. Validity. Is the string a real, assigned phone number? A format check catches typos for free, but it cannot tell a live subscriber from a plausible-but-unused range. The sms.gray-routes explainer and the carrier deactivation scrub guide cover what happens when validity goes stale: a number that was real in January can be deactivated by March, and you pay full price to message a dead line.
  2. Reachability. Is the subscriber attached to the network right now? An HLR (Home Location Register, the carrier's live subscriber database) dip answers this — on-network presence, plus the context that matters on its own: the serving carrier, the line type (mobile, fixed-line, or VoIP), the mobile country and network codes, whether the number was ported away from its original carrier, and whether it is roaming. This is the pre-send scrub: drop the rows that will bounce anyway and stop paying termination for them.
  3. SIM-swap risk. Was the SIM recently replaced under an account that should not have changed hardware? A SIM swap is the standard account-takeover move — an attacker convinces a carrier to move the victim's number to a SIM the attacker holds, and then every OTP you send goes to them. The check that catches it must run before the OTP issues, not as a log line after. The 2026 wave that moved this from an ops note to a board-level line item is covered in the SMS-pumping fraud explainer; this post is the product side.

A lookup result is only as useful as the decision it feeds. A validity answer feeds a scrub; a reachability answer feeds a send/no-send gate; a SIM-swap answer feeds a step-up (block the SMS, fall back to voice or email, or involve your risk engine). Evaluate lookup vendors on where their check fires in your flow, not on a feature-list cell.

Orbit's number-lookup surface

On Orbit, lookup is a first-class product on the NaaS pillar (Numbers & Network as a Service) — the same pillar that owns phone numbers, porting, and the eSIM/IoT catalog, exposed on one account and one pay-as-you-go bill. Three endpoints cover the whole problem:

  • Quick validation. POST /api/v1/numbers/lookup with { "phone": "+14155550100" } returns validity, country, line type, and HLR enrichment for one number. The full shape is user-addressable in the number-lookup docs.
  • Full intelligence dip. GET /api/v1/numbers/lookup/{phone} returns the complete record one number can answer: validity, calling-country code, the carrier block with its mobile country and network codes, the portability block (ported yes/no plus the original carrier), the SIM-swap block, the roaming block, live-reachability, and a cached flag. Devotel HLR is the primary source; a passing response carries what the upstream actually returned.
  • Data packages, Twilio Lookup v2 compatible. Add a fields= selector (comma-separated) and each requested intelligence package lands in a dataPackages map with a per-field status. Available today: line_type_intelligence, operator_name, phone_number_quality_score, sim_swap (carrier-asserted via CAMARA SIM Swap, GSMA Open Gateway, with a best-effort fallback when the carrier signal is absent), identity_match (CAMARA KYC Match — per-attribute verdicts, never the underlying PII), cnam, reassigned_number (US-only, requires a consent date), call_forwarding (derived, low confidence), number_reputation (derived, HLR-based), sms_pumping_risk (derived, pre-OTP), and live_activity (the real-time reachability composite on one call). The selector is case-insensitive, capped at sixteen fields per request, and an unknown field name rejects the whole request with 422. If your lookup-v2 migration script selects line_type_intelligence,sim_swap, it runs against the same shape without a rewrite.

The reference page for the whole surface — the per-field carrier matrix, per-field status semantics (available / coming_soon / not_implemented / error), and the request shapes — is the numbers API reference.

Acceptance patterns, and which one actually fits your flow

The product exists to feed three acceptance patterns. Match them against the flow you actually run, because a lookup pattern is only worth what it gates:

  1. A bulk list scrub before the campaign sends. POST /api/v1/numbers/bulk-lookup validates up to one hundred numbers per request. Run the buyers' template on the whole list at one time, drop the invalid and unreachable rows, and the send that follows is paying termination only for reachable lines. A porting window or a deactivation wave ages a list you cleaned in January — the scrub is a pre-send step, not a one-time migration. This maps to the "Clean your sending list" use case on the pillar page.
  2. A synchronous dip inside the Verify flow. The per-lookup decision runs inline in the Verify API lifecycle: the pre-send Fraud Guard scores the destination against the lookup signals, and a refused send returns synchronously — a 403 VERIFY_FRAUD_BLOCKED with the risk score and reasons attached — before any message is sent. The same skip decision emits a verification.fraud_blocked webhook event. A lookup that only lands in an analytics table never saved you a fraud dollar; one that refuses a send does.
  3. A SIM-swap gate before the OTP issues. The sim_swap data package carries the carrier-asserted verdict (swapped, lastSwapDate, riskLevel), and the Verify flow reads it before any OTP is created: a swap-arrived verdict blocks the SMS lane (SIM_SWAP_DETECTED), and the flow falls back to voice, email, or your own step-up. That is the pre-send check the buyer page implies but usually cannot answer after the paragraph ends — compare the row against the actual endpoint, not the brochure.

Which you need is a function of what you run. A marketing campaign runs on (1). An OTP surface runs on (2) plus (3). A fraud LM read in a support flow runs on the field= selector any of the packages above.

An API walk-through: reading the dip before the send

This is the same tenant-owned-controls shape as the compliance checklists — the platform exposes the endpoint, the per-lookup decision, and the spend levers; which verdicts block which sends is your policy call. A pre-send gate against the Verify flow reads exactly like this:

curl -X POST https://api.orbit.devotel.io/api/v1/numbers/lookup \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+14155550100" }'

The response tells you the number is valid, names the carrier, the line type, the ported flag, the roaming state, and whether the line is live. To read the SIM-swap signal before an OTP, request it as a data package on the full dip:

curl "https://api.orbit.devotel.io/api/v1/numbers/lookup/%2B14155550100?fields=sim_swap,line_type_intelligence" \
  -H "X-API-Key: dv_live_sk_..."

URL-encode the leading + as %2B. The dataPackages.sim_swap.data block carries swapped (boolean), lastSwapDate, and riskLevel. A swap-arrived verdict against your policy is the step-up trigger — block the SMS lane, fall back to voice or email, or pass the signal to your risk engine — not a discoverability note in a dashboard. The per-field statuses make degraded upstreams explicit instead of silent: a carrier-asserted value reads available, a carrier that does not expose the signal today reads coming_soon, and you can policy the difference.

Bulk is the same shape scaled out — one request, up to one hundred numbers:

curl -X POST https://api.orbit.devotel.io/api/v1/numbers/bulk-lookup \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "numbers": ["+14155550100", "+14155550101"] }'

The endpoint pre-checks your balance for N × unit price and fails fast with 402 before fanning out, then charges per successful result (a 100-number batch checks for about $1.00 of wallet headroom up front on the default rate). There is no per-lookup dashboard-only mitigation — the gate fires in the flow, not in a report.

The full payload shapes, the per-country carrier matrix, the per-package status semantics, and the migration notes are in the number-lookup docs and the numbers API reference.

Frequently asked questions

What is the difference between number reachability and SIM-swap?

Reachability answers "is the subscriber attached to the network now" — an HLR dip returns on-network presence, the line type, the ported flag, and the roaming state. SIM-swap answers "was the SIM replaced recently under this account" — a carrier-asserted flag dates the last SIM change. They are different signals that gate different decisions: a reachability verdict feeds a send/no-send scrub, a SIM-swap verdict feeds a step-up or an OTP block. One can read clean while the other blocks.

Is Orbit's lookup data carrier-grade, or a public-data tier?

The primary dip is carrier data — Devotel HLR against the live subscriber database — with Telnyx Lookup v2 as a fallback for fields HLR does not answer on a given number. The identity_match and sim_swap packages are operator-asserted through CAMARA (the GSMA Open Gateway shape) when the carrier is contracted; the per-field status shows that explicitly (available with provider named, coming_soon when the carrier is not yet contracted), so you can policy a degraded upstream instead of guessing. A public-data tier answers only a subset of this, and the dip records say which tier actually answered.

How is lookup billed?

On the number_lookup metering channel at the rate published on the Orbit pricing page (fallback 1¢ per query, with per-org overrides) — the channel reads familiar from the billing page the day you sign up. Single lookup is charged only after the upstream actually answers: a malformed number that never reaches the HLR is free. Bulk lookup pre-checks N × unit price and fails fast with 402 before fanning out. A per-tenant daily cost cap (default $50/day) returns 429 on an overage, sandbox (testMode) is never billed, and an insufficient balance returns 402 with the cents attached so you can top up. There is no second invoice for the pre-send gate — it is the same metering channel.

Published 2 September 2026.

Phone-Number Lookup and SIM-Swap Pre-Send — a CPaaS Buyer Guide — Orbit by Devotel