Quick answer: Phone number porting (local number portability, or LNP) is the regulated process that moves a number from your old carrier onto Orbit: confirm it is portable, collect the carrier record (CSR) and service address, pass a readiness gate, attach a signed Letter of Authorization (LOA), and wait for the losing carrier's Firm Order Commitment (FOC) date. On Orbit the whole flow is API-driven — a bulk portability check screens up to 1000 numbers per call, the platform signs and forwards the LOA, and a per-stage timeline plus webhooks tell you exactly where a port is stuck. For enterprise estates of hundreds of DIDs, a single bulk CSV upload creates every port request at once.
If your team is preparing a move off a legacy provider, the comparisons hub, alternatives to enterprise messaging and voice platforms, sets up the platform contrast; this guide covers the one step that carries real regulatory risk — the numbers — with the actual endpoints your engineers will call. Everything below maps onto the full number porting reference in the docs.
Why teams stay stuck on a carrier they have outgrown
The most expensive line in a legacy telecom contract is rarely the per-minute rate — it is the phone numbers themselves. Voice minutes and SMS feeds are commodities you can exit, but your numbers are the identity your customers save, the sender records carriers trust, and the upper bound on any vendor evaluation: the platform you would rather run stays hypothetical because "we can't move the numbers."
Number lock-in distorts platform economics in a second way. Teams that internalize "the numbers can never leave" will accept contract terms, feature gaps, and per-seat pricing they would never accept on a clean procurement exercise — the lock-in is priced in, silently.
The asymmetry is real but survivable. LNP exists as a regulated right precisely because carriers could not be trusted to trade numbers voluntarily. The work is procedural: prove you own the number, hand the losing carrier a valid LOA, clear whatever data mismatch they kick back, and wait out their review window. Teams stall when they treat the procedure as folklore instead of a checklist — the numbers move when someone runs the checklist on purpose. On Orbit that checklist is a formal state machine, so a migration stops being a memory exercise and becomes an operational queue.
What a port actually requires
A carrier will not move a number on your say-so. The winning carrier has to prove to the losing one that you genuinely control the account that number is billed under, and the regulatory regime decides what proof qualifies. Before an LOA is drafted, four gates have to pass.
Portability check. A number can refuse to move: an unsupported rate center, a country without an LNP regime, a wireless-only cluster, a number already inside another pending port. Screening the whole estate up front is what separates a planned migration from a pile of rejections. Orbit's portability check — one number or up to 1000 in a single POST /v1/numbers/porting/check/bulk call — clears this gate for the entire list before anyone drafts paperwork.
Carrier record and address validation. The losing carrier verifies a port-out against its billing record — the Customer Service Record (CSR). The account number, the authorized end user, and the exact service address have to match that record character-for-character; "Suite 200" written as "Ste 200" is a rejection when the CSR says "Suite 200". None of this is visible from your invoice; you extract it from the carrier or reset the window.
Combined readiness gate. Because CSR and address checks depend on portability first, Orbit collapses both into POST /v1/numbers/porting/pre-validate — one call per batch answers "portable, and the data we would hand the losing carrier is internally consistent" before the request is dispatched (see the porting reference for the field topology).
A scoped authorization. Carriers require a documented agent appointment — the LOA downstream — before they will entertain a port order. The gate exists at every scale: even when bulk migration funnels hundreds of numbers into CSV rows, each row still names the account and billing address the carrier will hold the port to.
The LOA in practice: upload, sign, forward
The Letter of Authorization is the instrument the losing carrier must honor — it declares that the named signer, for the listed service address and account, appoints Orbit to move the numbers. Every port request rises or stalls on the LOA, so the platform makes it a first-class object rather than a file attachment.
The lifecycle is explicit (full reference):
- Upload the artefact — PDF, JPEG, PNG, or HEIC up to 10MB — against the porting request.
- Sign in-platform: capture the signer name, email, and acknowledgement text through
POST /v1/numbers/porting/:id/loa/sign, sourced from a typed dashboard signature or an API call. - Submit the signed LOA to the losing carrier with
/loa/submit— the step that formally opens the carrier review clock.
Each step flips a draft → signed → submitted state, and signing twice returns 422 — the state machine forbids the silent-rewrite failure modes (version mismatch between unsigned drafts) that make manual LOA handling error-prone. The upload accepts a by-hand signature where a wet-ink form is legally required; the in-platform signature covers the common e-acknowledgement case.
Rejections are not the end. When the losing carrier kicks back a supplement request — usually one address line or a suite detail — the amend window is 7 days before the FOC clock resets. Orbit exposes POST /v1/numbers/porting/:id/supplement and a porting.request.supplement_submitted webhook, so the correction ships inside the window rather than restarting the calendar.
Timelines, FOC, and doing something while you wait
Simple ports clear in 3-15 business days; complex multi-line ports and countries with manual carrier processing take longer. Duration risk is not hidden — the problem is that losing carriers surface one opaque status, which turns "waiting" into "no idea where it sits."
Orbit expands that flat status into a per-stage timeline (GET /v1/numbers/porting/:id/timeline) across submitted → validating_loa → carrier_review → foc_assigned → foc_scheduled → completed, each stamped with when it entered (timeline reference). Operations teams watch the exact stage; a stall in carrier_review looks different from a stall in validating_loa, and only one of them is operator-fixable.
The event a losing carrier actually commits to — the Firm Order Commitment (FOC) date — is echoed on the timeline once assigned and drives the cut-over window your team schedules. A rejected state returns the translated carrier code with severity: operator_fixable (re-upload the corrected LOA), needs_carrier (escalation), or fatal (stop; the number cannot move). Polling a timeline on a loop is the wrong pattern — the right one is a webhook subscription: number.ported, porting.request.loa_signed, porting.request.supplement_submitted, porting.request.manual_review_required, and porting.request.cancelled (event catalog).
Inbound traffic stays live on the old carrier until FOC executes, so plan a controlled switch: your traffic lands on Orbit the moment the port completes. Webhooks drive that cut-over automatically — subscribe and flip routing in code, not in a calendar reminder.
Bulk migration: the enterprise CSV path
When the estate is hundreds of DIDs, the per-number form is the bottleneck. The bulk endpoint — POST /v1/numbers/port-in/bulk-csv (bulk reference) — accepts a single CSV with phone_number, current_carrier_account_number, current_carrier_name, billing_name, billing_address columns and fans every row out to its own porting request in seconds: a 2MB file, up to 1000 rows per request, within a 30-second processing budget.
The endpoint reports both sides of the batch — the created request IDs and the per-row validation failures, in the same response — so a malformed row never silently falls out. The remaining per-number work (LOA attach, country dispatch) runs through the normal dashboard or API flow on each spawned request.
Two pragmatic rules for large estates. Split a ledger larger than 1000 rows across multiple uploads rather than retrying a timed-out one — the endpoint is rate-limited at 2 requests per minute per organization to keep retries honest. And run the bulk portability check across the ledger first; screening 500 numbers before you dispatch them is cheaper than absorbing 50 rejections.
Most enterprises do not wait for every LOA to be perfect before moving — the waves the migrate-from-enterprise-CCaaS guide lays out apply here too: protect the biggest queue first, move numbers in scheduled batches.
What to set up once the port completes
Landing a ported number is not finishing — it is clearing the way for provisioning. The number moves to your account with none of the regulated identities configured, and the providers you route traffic through will not treat it as production-ready until those records exist.
- E911 emergency address. When the ported number will carry voice, register and validate its per-number dispatchable emergency address before routing (emergency-address guide).
- CNAM caller name. Register the branded caller-name recipients see, and remediate "Spam Likely"/"Scam Likely" labels from the carrier CNAM database (CNAM guide).
- Lifecycle and ownership. The ported number enters Orbit's standard lifecycle — auto-renew, subaccount reassignment, scheduled release, the documented trial-expiry rules — through the number lifecycle reference. An enterprise numbering plan should reach that document before a port finishes, not after a renewal page fires.
- Onboard the channel. With the number vested, SMS sender registration, voice routing into the UCaaS cloud phone pillar, and identification as a customer-data record against the native CDP all become available.
The lifecycle page is worth reading before the port completes. It defines what happens to numbers after you own them — and the more important question in a migration, what stops you from losing one.
Frequently asked questions
How long does the port actually take?
Simple ports clear in 3-15 business days once the FOC is assigned; complex multi-line ports and countries with manual carrier processing run longer. The clock runs per-stage — the Orbit timeline view shows whether the request sits in LOA validation or carrier review, so "waiting on the losing carrier" is a measured state, not a mystery.
What happens to the number while the port is in flight?
It stays live on the losing carrier. Inbound traffic and callers see no interruption until the Firm Order Commitment executes, at which point the number lands on your Orbit account and the old carrier stops serving it.
Can I port an entire enterprise DID estate at once?
Yes — the bulk CSV endpoint creates a separate porting request per row (up to 1000 per upload), with per-row validation errors reported in the same response. The remaining per-number work (LOA attach, country dispatch) runs through the standard flow on each spawned request.
What does the losing carrier verify on the LOA?
The account number, the authorized end user, and the exact service address from its Customer Service Record (CSR). Mismatches as small as "Suite" vs "Ste" reject the port; the pre-validate readiness gate catches the internal-consistency failures before dispatch.
What is FOC, and why does it matter?
A Firm Order Commitment is the losing carrier's committed cut-over date. It is the anchor of your migration calendar: inbound stays on the old carrier until FOC executes, so teams schedule traffic flips and queue cut-overs against it.
Where do carriers fit in Orbit's stack?
Orbit runs its own carrier operation — Devotel's wholesale softswitch terminates calls once the ported number is live, and Devotel's DIDWW and Telnyx relationships act as the inbound leg of the path. The port FOCs on a carrier you name; ongoing inbound termination lands on Devotel's network.