Skip to main content

Desk-phone fleet rollout

Extensions and desk phones and Desk phones: zero-touch provisioning cover the console flow end to end. This guide is the runbook for the other half of a real install: the monitor and recovery loop of a bulk rollout, from the MAC export to handing facilities a working floor. It assumes one workspace, one site, and a fleet of Polycom, Yealink, Cisco, or Grandstream handsets. Everything here is available to the owner and admin roles.

Pre-stage the fleet

Do this before any phone is unboxed:
  • Handsets on hand. Confirm every SKU is one of the four supported vendors: Polycom, Yealink, Cisco, Grandstream. The importer rejects any other vendor row by row.
  • MAC list exported. Pull the MACs from the vendor shipping manifest or the carton labels into one spreadsheet, one row per phone, and dedupe it before upload. The importer normalises : , - and . separators, so 00:04:f2:aa:bb:cc and 00-04-F2-AA-BB-CC are the same phone; dedupe on the normalised form, not the raw string.
  • Extensions pre-created. Create one extension per phone (plus a handful of spares) under Voice → Extensions before zero-touch day. Give each a 2–8 digit extension number from a reserved range (for example 2101–2300 for a 200-seat floor) so colleagues can short-dial, and keep a label convention that matches the phone label column below (FL1-101, FL1-102, …). Pairing later is a picker, not a form: the extension has to exist to be picked.
  • Network ready. The redirect servers are the vendor clouds (Polycom ZTP, Yealink RPS, Cisco EDOS, Grandstream GDMS), so there is no on-prem TFTP server and no DHCP option to maintain. The handsets need HTTPS egress to the vendor portal and to the Orbit SIP edge over TLS, power (PoE switch ports or adapters), and whatever voice-VLAN hygiene you already run. Disable SIP-ALG on the site router; it rewrites SIP headers and breaks REGISTER bindings.
  • Rate window planned. Registration is limited to 50 phones per hour per workspace, and the bulk importer posts rows one at a time against that window. A 200-phone fleet is four uploads, an hour apart. Schedule them; do not fight the window. Uploads of more than 50 rows run until the window fills, and the surplus rows land in the failed list with a rate-limit reason.
The CSV template below is the file you will upload in the next step; build it from the deduped MAC export and your label convention:

Bulk-register by MAC

In Voice → Desk phones, click Bulk import and upload the CSV. The header row is required; mac and vendor are required columns, label and model optional. Column order and case do not matter, and common aliases are accepted (mac address, make, manufacturer, name, description). The preview stage shows how many rows are ready and lists parse rejections with line numbers before anything is posted. After the import, the result panel reports three counts:
  • Registered — the row created a device. The phone now has a provisioning URL and a 30-day claim window.
  • Skipped — the row never reached the server: a cell that does not reduce to a 12-digit hex MAC, or a vendor outside the four supported. Fix the line and re-upload.
  • Failed — the server refused the row: a duplicate MAC (with the row’s line number), or a MAC live in another workspace. Everything else in the batch is unaffected.
Re-uploading is safe and is the intended recovery loop: rows that registered on a previous upload report as duplicates in the failed list, not as errors, and the new rows register. Keep the same file, fix the rejected lines, upload again. For the 200-phone template above, upload rows in batches of 50 or fewer per hour. The result panel’s per-line reasons are your source of truth; export the failed list before closing the dialog.

Pair phones to extensions

A registered phone is inert until it is paired with a SIP credential. There are two lanes; pick per batch, not per phone:
  • Single create with pairing — the Register desk phone dialog (or POST /api/v1/voice/devices with sipCredentialId) registers and pairs in one step. Use it for day-two additions, replacements, and small batches where the extension is known at register time.
  • Bulk CSV now, pair after — the CSV lane registers only (mac, vendor, label, model; there is no credential column). After the batch registers, pair each device from its row in Voice → Desk phones, or with PATCH /api/v1/voice/devices/:id setting sipCredentialId. Use this for the fleet: registration is the rate-limited step, pairing is not, so register the whole batch first and pair at your pace.
Two rules for the pairing pass:
  • An extension pairs to a phone by picking it; Orbit does not reserve an extension to one device. If you pair two phones to the same extension, both ring as that extension. For one phone per seat, pair a dedicated extension and keep shared extensions deliberate.
  • Pairing a credential that does not exist in this workspace fails with a 404. The guard does not confirm or deny credentials outside your workspace; double-check the id came from Voice → Extensions.
Pair every row before zero-touch day where you can. A phone that boots unpaired fetches its config and receives a refusal; that attempt does not spend the one-shot provisioning URL, so once you pair the row the next boot provisions cleanly. Booting paired is still the calmer order.

Zero-touch day

Each phone already knows how to reach its vendor cloud on first boot; the vendor cloud hands it your provisioning URL. For every MAC, the record the portal carries is the MAC plus the device’s provisioning URL (on the device row in Voice → Desk phones, and in the create response if you registered via API):
Enter the MAC in the notation the portal prints; the URL is pasted verbatim, token included. Where the vendor cloud accepted the mapping automatically at create time (the create response and the audit log say so), the record is already there and the portal entry is a verification, not a setup step. For vendors without auto-registration, the manual entry is the setup.
The provisioning URL carries a signed, single-use token bound to the MAC. The export of MAC→URL records is a credentials file: store it like one, and never email it as plain text in the body.
On the day, facilities powers the phones (network + PoE), and each handset factory-reset boots through its redirect, pulls its rendered config, and registers. “Came online” is two signals agreeing:
  1. Voice → Desk phones — the device row shows a last provisioning fetch with timestamp and source IP. The config left the building.
  2. Voice → Extensions → the paired extension — the Live status card reads Registered, with the UTC time and source IP of the last REGISTER. The phone is on the SIP edge.
Expect the floor to come up in waves as phones boot; a 200-phone floor typically settles within the hour.

Verify the floor

Spot-check online status from the API instead of clicking 200 rows. GET /api/v1/voice/devices returns each device with macAddress, label, sipCredentialId, provisioningLockedAt (set when the phone fetched its config), claimExpiresAt, and disabled, paginated by cursor (limit up to 200; follow next_cursor for larger fleets):
Every row should read paired / fetched / active. The three bad readings map to three recovery loops:
  • UNPAIRED — the pairing pass missed the row. Pair it from the device row; the phone provisions on its next boot with no further action.
  • NOT-FETCHED — the phone never reached its redirect. Confirm the vendor portal carries the exact MAC→URL record, confirm the handset is powered and has egress, then factory-reset it. If the claim window expired in transit (the row reads Expired), run Rotate provisioning URL on the row and reset the phone; rotation re-opens the window.
  • Fetched but Not registered — the config left our side and the REGISTER is failing at the site. Check the extension’s Live status card: if it flips Registered → Not registered, the re-register is failing. Confirm the password has not rotated since the phone fetched, that SIP-ALG is off, and that the site allows TLS egress to the SIP edge. If an allowed-source-IP list is set on the extension, the phone’s egress IP must match it.
The phone-side indicator for the last class is the extension’s Not registered state (the binding expired); brief gaps self-heal because phones re-REGISTER every 60–300 seconds, so act on persistent readings, not a single poll. When a handset is genuinely wedged, the clean re-provision is: rotate the extension’s password, delete the device row, re-register the MAC (it re-tickets as a fresh device), re-pair, and factory-reset the phone.

Failure reference

Handoff and day two

Hand facilities a one-page walk-through so day one does not need you in the room:
  1. Connect network and power (PoE or adapter); wait for the boot sequence to finish. The phone shows its label and extension once registered.
  2. Place an internal call to a colleague’s extension number from the reserved range; then one external call.
  3. If the remote phonebook or line keys are enabled for the workspace, the colleague list and BLF keys arrive with the config; a missing directory is a phonebook setting, not a failed rollout.
  4. A phone stuck mid-boot gets one factory reset before it becomes your problem; the recovery loop above is yours.
Day-two additions and single replacements use the single-phone flow: Register desk phone, pair, paste or confirm the redirect entry, reset the handset. The full per-step console and API reference is Desk phones: zero-touch provisioning; the credential lifecycle (rotate, disable, delete) is Extensions: reference. All SIP traffic the provisioned phones carry exits through the Devotel wholesale softswitch; the rendered config points handsets at the Devotel-routed SIP edge only. There is nothing to configure for this; it is stated so a network team auditing the floor knows what to expect.

More