Skip to main content

Number reuse, aging, and post-release posture

Releasing a number is not a single moment. Between POST /numbers/:id/release (or a scheduled / parking-expiry release) and the day a completely different organization buys the same digits, the number moves through a controlled sequence: an in-account grace window, a region-sized aging wait, a carrier-side cooldown, and only then a return to the buyable pool. This page is the posture reference for that sequence — why reuse is controlled, how long each stage lasts, what the next owner inherits, and what happens when the carrier refuses to let go. The six status values themselves are defined in Number status map; the step-by-step operations live in Number lifecycle.

The released-number pool and why reuse is controlled

Orbit resells carrier inventory. When you release a DID, the digits do not disappear — they go back to the carrier’s inventory and eventually reappear in GET /numbers/search results for other tenants. Uncontrolled reuse would be a trust-safety failure: a scam corridor’s sender could be recycled onto an innocent tenant within hours, the prior tenant could lose a number they meant to keep, and two organizations could answer the same inbound webhook. Three controls make reuse deliberate instead:
  • An in-account grace window. A release you initiate (or schedule) parks the number first. During parking the number is still yours — nobody else can buy it — and POST /numbers/:id/reclaim restores it to active without a fresh purchase.
  • A region-sized aging floor. The parked window is set per country (30 / 45 / 90 days) so a release-then-rebuy by the same tenant never collides with the carrier’s own post-release quarantine.
  • A durable release pipeline. The carrier DELETE is a queued operation with a retry budget, not a best-effort fire-and-forget — so a number never reads released in Orbit while the carrier still considers it assigned.

Aging states — release to eligible-for-repurchase

The tenant-facing states are active → parked → released. Behind them sits a longer timeline the row status does not fully show:
  1. parked — in-account grace. The number is still assigned to you. The grace lasts the longer of (a) your paid-through billing date and (b) the regional aging floor below. Until it closes, reclaim is one API call.
  2. released — upstream hand-back. When the window closes, the parking-expiry scheduler issues the carrier release and the row flips to released. This state is terminal: the only path back is a fresh purchase.
  3. Carrier-side cooldown. After Orbit’s release completes, the carrier applies its own aging policy before re-listing the number — the FCC Reassigned Numbers Database aging rule in the US, CRTC-aligned windows in Canada. That rule binds carriers, not Orbit; Orbit’s parking floor is sized to sit comfortably ahead of it.
  4. Eligible for repurchase. The number re-enters the sellable pool. A search for the same region can now surface it to any tenant — possibly back to you, if you bought it again intentionally.

Aging policy table

The parking window is a platform grace — the time the prior tenant gets to reclaim — not a regulatory minimum. Carriers enforce their own post-release aging independently on top of it. If your next_billing_at is further out than the regional floor — you released right after a renewal — the window extends to the paid-through date instead. You always get at least the regional floor, and at least the time you already paid for.

What resets and what persists across reassignment

When a number reaches a new owner, ownership-scoped state is cleanly split along one line: your tenant schema resets; the carrier’s view persists. Resets with the release (tenant-scoped, never carried across owners):
  • Routing and configuration. Messaging profiles, voice connections, inbound routes, labels, and capability attachments belong to your tenant schema. The row that held them is terminal at released; a new owner’s purchase provisions fresh configuration against their own account.
  • Your suppression ledger. Opt-outs, DNC entries, and consent records you accumulated against this number as a sender live in your own suppression list. They stay in your account — they still gate your sends to those recipients — but the next owner does not inherit them. Their suppression list starts empty. Suppression entries are scoped by address, not by sender number; see Consent, opt-out, and suppression.
  • Account-side identifiers. The num_... id, subaccount assignment, and your audit trail are yours. A repurchase mints a new row.
Persists with the number itself (carrier-scoped, outside Orbit’s control):
  • Carrier spam labels and reputation. A number flagged as spam by a handset or analytics vendor carries that label into its next ownership. The aging windows above exist partly for this reason — a cooling-off period reduces the chance the next legitimate owner inherits a hot label.
  • Downstream-corridor reputation. The shared, anonymized fraud-reputation feed keys on destination corridors (E.164 prefixes, MCCMNCs), never on the sender’s identity or the specific sending number. A scam tenant’s blocks accrue to the corridor they targeted, not to the DID they used — so releasing their number does not launder the corridor, and the next owner of the DID is not scored by it either.
  • Regulatory cooldowns. Carrier-side aging (FCC RND, CRTC windows) was designed precisely so a recycled number does not arrive at a new subscriber seconds after the old one dropped it. Orbit’s grace window stacks ahead of that, not instead of it.
The trust-safety asymmetry to hold onto: what protects recipients (the corridor feed, suppression addresses) is deliberately detached from the sending number, so burning a number and buying a new one buys a scammer nothing — and what protects the next owner (aging windows, carrier cooldown) is deliberately detached from the previous owner’s account.

The number-release-retry worker

A release is not answered inline. Flipping your row to released is cheap; the carrier DELETE it implies is not — it can hit a 5xx, a network blip, or a regulatory hold. If that failure were swallowed, Orbit would show released while the carrier still owned the number, and inbound traffic would keep arriving at a number you no longer hold. So the upstream release is a durable queued operation:
  • Queued, with a bounded retry budget. The first release attempt runs in-call. A failure flips the row’s release tracking to pending and enqueues a retry job; the worker re-issues the carrier DELETE on a 1 minute → 5 minutes → 30 minutes schedule (three attempts). The queue payload rides Redis, so it survives an API or worker restart — the same backbone described in How Orbit processes work asynchronously.
  • Idempotent by construction. Before issuing the DELETE, the worker re-reads the row. A number that came back to active — you reclaimed it, or reactivated it — is never released upstream; the worker reconciles the release tracking to its terminal baseline instead. A carrier response of “no such number” is accepted as success: the carrier letting go is the goal, however it was reached.
  • Exhaustion is visible, not silent. When the retry budget runs out, the row’s release tracking reads failed, the number shows a Retry release prompt on your Numbers page, and POST /numbers/:id/retry-release re-enqueues the sequence. A carrier rejection is surfaced to you as an actionable state, never as a quietly wrong one.
The contract this gives you: a number may say released before the carrier has confirmed, but it can never stay that way unnoticed — the retry pipeline closes the gap, and the failed state is yours to act on.

Tenant-visible guarantees

Six guarantees you can rely on as a tenant:
  1. Release is never instant-to-resale. Between your release and the number’s reappearance in the pool there is always the full parking window — 30/45/90 days by region, or your paid-through date if later. Nobody buys your number out from under you the same day.
  2. Reclaim is free during the window. POST /numbers/:id/reclaim restores a parked number to active with its configuration intact — no re-purchase, no re-provisioning charge.
  3. A stuck release is surfaced. A failed carrier release shows up as failed release tracking on the number’s row, with a retry affordance — not as a number that died silently.
  4. The next owner starts clean. Your routes, messaging profiles, suppression ledger, and audit history never transfer. They buy the digits, not your account.
  5. Carrier reputation is aged, not erased. Post-release cooldowns (yours plus the carrier’s) reduce inherited spam labels — but they are a posture, not a guarantee. If a newly purchased number arrives with residual labels, the spam-label snapshot on the number’s health surface is where that shows up.
  6. Release is one-way by design. released is the only terminal state in the number lifecycle. If you are not sure, park (schedule) the release and keep the reclaim window open rather than releasing outright.

Relationship to fraud and suppression

The reuse policy is deliberately asymmetrical against two abuse shapes:
  • A scam tenant cannot launder reputation by churning numbers. The shared corridor reputation feed is keyed on the destination corridor, not the sending DID. Releasing the number and buying a fresh one leaves the corridor’s corroborated block history exactly where it was — the SMS-pumping score does not reset with the digits.
  • A scam number does not instantly recycle onto an innocent tenant. The same tenant’s churn is throttled by the aging windows above: 30/45/90 days of platform grace plus the carrier’s own cooldown before re-listing. By the time the number is buyable again, handset- and carrier-side spam labels have had a full aging cycle to decay.
Your own suppression posture is unaffected by a release: opt-outs and DNC entries remain in your ledger and keep gating your sends. Suppression is a property of the recipient address under your consent policy, not of the number you sent from.

What this is not

  • Not port-out. Porting out is a transfer of ownership to another carrier; the number leaves Orbit’s inventory entirely and never re-enters the pool. That flow has its own state, concurrency guards, and PIN control — see Port-out lifecycle and ownership model.
  • Not parking as a product feature. parked here is the release-path grace state, not a long-term holding product. There is no “park this number indefinitely” — the window always closes toward released.
  • Not the trial pool. Trial numbers are claimed from and returned to a shared pool with their own rules (Trial & shared-pool numbers); the aging windows on this page govern purchased DIDs.

See also