Port-outs
A port-out happens when another carrier — on behalf of the end user — requests one of your numbers. Regulations require these to be honored unless there is a legitimate reason to reject, and decisions have deadlines.
How it reaches you
When a provider notifies us of a port-out request, we validate it against your
numbers registry and emit a port_out.created webhook. What happens next
depends on your account's port-out policy:
| Policy | Behavior |
|---|---|
auto_approve (default) |
If the number has a port_out_pin set, the requester's PIN must match; otherwise the request is approved automatically. Wrong PIN → auto-rejected with reason pin_mismatch. |
manual |
The request is held in action_required and you must decide via the API within the deadline (24h by default). |
Switch policy at any time:
curl -X PATCH https://api.example.com/v2/account/settings \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"settings": {"port_out_policy": "manual"}}'
Protecting numbers with a PIN
curl -X PATCH https://api.example.com/v2/numbers/{number_id} \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"port_out_pin": "4821"}'
Share the PIN with the legitimate end user; a gaining carrier must present it for auto-approval.
Deciding manually
curl https://api.example.com/v2/port_out_requests?status=action_required \
-H "Authorization: Bearer pk_live_YOUR_KEY"
curl -X POST https://api.example.com/v2/port_out_requests/{id}/approve \
-H "Authorization: Bearer pk_live_YOUR_KEY"
curl -X POST https://api.example.com/v2/port_out_requests/{id}/reject \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "account holder did not authorize this transfer"}'
Rules:
- Rejections require a reason — it is kept as a regulatory audit trail.
- Undecided requests expire at
deadline_at(statusexpired), which in practice usually lets the port proceed on the provider side. Do not sit on requests. - Requests for numbers we don't manage are auto-rejected and never reach you.
Lifecycle
pending → action_required (manual only) → approved | rejected | expired,
then completed when the number actually leaves. On completion the number's
registry status becomes ported_out, its routing is torn down, and you receive
number.ported_out.