docs

Port-in / port-out

Mobile Number Portability (MNP) is the most subtle flow in the platform. The carrier drives timing; heliumOS brokers the handshake and emits events your app can act on.

Port-in state diagram

Port-in sequence

Port-out

Initiated by the gaining carrier, delivered to heliumOS as an inbound webhook. heliumOS normalizes it and emits port_out.requested to your registered endpoints. You have a carrier-imposed validation window to respond (typically 24 hours).

A payer porting out ends the group plan

When the payer of a group plan ports their own number out, the plan they were paying for ends with it. The subscription is cancelled the moment the port completes, and every other line on it is deactivated in the same second. A deactivated line can no longer be ported, so a member who wanted to keep their number cannot take it anywhere afterwards.

GET and POST /v1/sims/{sim_id}/port_out_pin both return port_out_ends_other_lines: the number of other lines that lose service when this line's port-out completes. It is 0 for a member's line and for a single-line plan, and non-zero only for a group plan's payer. When it is non-zero:

  1. Tell the payer before you hand them the PIN that every other line on the plan ends with theirs.
  2. Port out any member who wants to keep their number first. Each member line has its own PIN.
  3. Only then let the payer's port complete.

A member's own port-out never affects the rest of the plan: only their line is removed, and the payer keeps paying for the others.

Where the number went

When a port-out completes, the carrier names the carrier that took the number. The completed port carries it as gaining_carrier, on GET /v1/ports/{id}, on the list, and on the port.out_completed event:

"gaining_carrier": {
  "spid": "6006",
  "name": "VERIZON WIRELESS",
  "display_name": "Verizon"
}

spid is the gaining carrier's Service Provider ID. name is the number-portability registry's label, verbatim, and is sometimes truncated. display_name is the one to show a person: the brand for a known spid, otherwise name with the registry's suffixes removed. gaining_carrier is null on port-ins and on port-outs that have not completed.

Common rejection reasons

CodeWhat it means
wrong_account_numberSubscriber-supplied account on file with losing carrier didn't match
wrong_pinPort-out PIN / transfer PIN didn't match
number_not_portableLosing carrier doesn't support MNP for this line type
name_mismatchAccount holder name didn't match
pending_portA port is already in flight for this number

Surface the reason verbatim in your UI — it tells the subscriber exactly what to fix with their losing carrier.