Number backorder waitlist
When the number you want is out of stock at the provider, the synchronous buy flow cannot help — there is nothing to search, select, or purchase. The backorder waitlist lets you register a standing request for a specific(country, area code, number type) pool and poll the same live provider
inventory the buy flow uses, so the moment matching stock reappears you can
place the order instead of manually re-running the search page.
This guide covers what the waitlist is, the entry lifecycle, the dashboard
walkthrough, an automation pattern, the limits and behaviour, and when to
reach for the waitlist instead of the replenishment policy or a low-stock
alert.
What the waitlist is
A waitlist entry is a standing backorder for a pool of numbers that is currently exhausted at the provider —GET /api/v1/numbers/available
returns no rows for the (country, area code, number type) combination you
want. You tell Orbit what you are waiting for and how many you want, and the
availability check re-runs the live, cross-provider inventory search
(Telnyx + DIDWW + Devotel) on demand until the pool reports enough depth
to satisfy your request.
The waitlist is distinct from two supply-side surfaces that both presume
availability and therefore cannot help when a pool is empty:
The buy flow answers “the number is in stock — take it now”. Replenishment
answers “I own a pool and it is running low — top it up from orderable stock”.
The low-stock alert answers “warn me before my owned bucket empties”. The
waitlist answers “the number is out of stock — tell me when it comes back”.
The lifecycle
The waitlist is a four-endpoint surface. All routes are tenant-scoped and require thenumbers:write scope (reads work with numbers:read).
1. Create an entry
Subscribe to a backorder withPOST /api/v1/numbers/waitlist:
The server assigns
id, created_at, and created_by and returns the stored
entry:
(country, area_code, number_type) already on
your waitlist — returns 409 WAITLIST_DUPLICATE with the existing_entry_id,
so the waitlist cannot fill with repeated subscriptions to the same pool. The
hard ceiling is 50 entries per organization; exceeding it returns
422 WAITLIST_LIMIT_REACHED.
2. Poll availability
GET /api/v1/numbers/waitlist/availability runs a live provider inventory
search for every enabled entry and reports whether each pool has restocked
enough to satisfy the request:
An entry is fulfillable when the live available count is at least the
entry’s
quantity. The availability check fans out to up to 15 enabled
entries per request (one cross-provider search each, concurrency bounded to
3). When your enabled set exceeds that cap, summary.truncated is true and
the response flags it — narrow the check with ?entry_id=<id> to poll a
specific entry.
To check a single entry, pass its id:
3. Place the purchase
The waitlist never buys on your behalf. When an entry returnsfulfillable: true, place the order through the normal buy flow — the inventory is now
present:
GET /numbers/available?country=US&type=local with the entry’s filters to
select the concrete E.164 numbers, then pass them to POST /numbers/buy-bulk
(up to 50 per call) or POST /numbers/purchase one at a time. The buy flow
wallet preflight, per-number mutex, and per-line error handling all apply
unchanged — the waitlist only tells you stock exists; it does not reserve it.
Stock can turn over between your availability poll and your purchase, so treat
fulfillable: true as “re-check and buy now”, not as a hold.
4. Unsubscribe
Remove an entry withDELETE /api/v1/numbers/waitlist/:entryId:
200 with { removed: true, entry_id }. An unknown id returns
404 WAITLIST_ENTRY_NOT_FOUND.
Persistence
The waitlist lives onorganizations.settings.numbers.waitlist as JSONB —
the same per-organization store the replenishment policy and low-stock
threshold already use, so no migration is required. Adding or removing an
entry is a read-modify-write of that blob, org-scoped by tenant id. A
malformed entry in the blob is dropped individually rather than discarding
the whole list, and any lookup or parse failure yields the empty waitlist.
Dashboard walkthrough
Standing entries appear on the Numbers page under a Waitlist tab. Each row shows the country, area code, number type, requested quantity, and the last availability result. The Recheck availability action on a row runs the same live provider search asGET /numbers/waitlist/availability for
that entry interactively, so you can poll a single pool without waiting on a
scheduled sweep.
When an entry returns fulfillable: true, the row surfaces a Buy now
action that drops you into the buy flow pre-filtered to that entry’s
(country, area code, number type) — the same search you would run
manually, with the filters filled in. The waitlist does not hold the stock;
the action re-searches live inventory at click time, so act on a match
promptly.
Automation pattern
A typical integration subscribes a backorder entry, polls availability on a schedule, and fires a purchase when an entry returnsfulfillable: true.
The waitlist does not push a notification — it is a poll-driven surface — so
the integration supplies the cadence.
1. Subscribe once
2. Poll on a schedule
RunGET /numbers/waitlist/availability on a cadence appropriate to how
quickly stock turns in the target market. Each entry costs one
cross-provider live search, and the sweep is bounded to 15 entries per call,
so a 15–30 minute interval is a reasonable default for a handful of entries:
summary.truncated is true, your enabled set exceeds the per-request
cap — poll the remaining entries with ?entry_id= in subsequent calls, or
disable entries you no longer need.
3. Buy when an entry is fulfillable
For every result wherefulfillable is true, re-search the concrete
inventory and place the purchase:
NUMBER_NO_LONGER_AVAILABLE per-line failures the same way the buy
flow does — failed rows are never charged, so re-search the remaining
quantity and retry only the replacements. After the purchase lands, remove
the entry with DELETE /numbers/waitlist/:entryId if it is fully satisfied,
or leave it in place if you want to keep waiting for more depth.
A minimal Node.js loop:
Limits and behaviour
The waitlist is poll-driven: there is no pushed notification when stock
reappears. The
number.inventory.low webhook event covers your owned
low-stock buckets; it does not fire for a backorder entry. Your integration
supplies the poll cadence via GET /numbers/waitlist/availability.
The availability check is a pure provider inventory read — it runs the
same cross-provider search the buy flow uses and reports depth. It does not
reserve, hold, or purchase anything, and it never touches an outbound
voice/SMS path. Stock can turn over between a poll and a purchase, so a
fulfillable: true result means “re-check and buy now”, not a held
reservation.
When to use the waitlist vs replenishment vs a low-stock alert
The three supply-side surfaces answer different questions. Pick by the state of the pool you care about:
A useful shorthand: the buy flow is for stock that is present, the
replenishment policy is for stock you own that is running low, the
low-stock alert warns you before an owned bucket empties, and the
waitlist is for stock that does not exist yet. If
GET /numbers/available returns rows for your target, you do not need the
waitlist — buy directly. Reach for the waitlist only when the search is
empty for the pool you want.
See Also
- Phone Numbers — the Numbers pillar surface: search, purchase, routing, porting.
- Number Lifecycle — auto-renew, scheduled release, reassign, reclaim, and the trial pool.
- Trial & shared-pool number model — the one free trial claim and the 24-hour lease.
- Inventory & Export — list and export what you own, plus the low-stock alert surface.
- Buy and provision numbers — the single-purchase and bulk-order walkthrough the waitlist hands off to.
- Numbers API reference — the full endpoint surface.