Skip to main content

Desk phones: zero-touch provisioning

Zero-touch provisioning (ZTP) attaches a physical desk phone to your workspace without typing SIP settings into the handset. You register the phone’s MAC address once, hand its vendor’s redirect server a provisioning URL, and the phone pulls a rendered, vendor-shaped config on its next boot — SIP server, credential pair, label — and registers. Everything else runs server-side. Supported vendors: Polycom, Yealink, Cisco, and Grandstream. All SIP traffic the phone receives exits through the Devotel wholesale softswitch. The provisioning URL hands the phone the Devotel-routed SIP edge only — no provisioned phone ever registers directly at Telnyx or DIDWW. You do not configure any of this; it is the platform’s routing contract, stated here so a network team auditing traffic knows what to expect. New to this area? Start with Extensions and desk phones for the create-the-extension walkthrough; use this page for the provisioning lifecycle in depth and for the API.

Where it lives

Open Voice → Desk phones in the dashboard (/voice/devices under your locale). The surface is gated to owner and admin roles — other roles see neither the page nor the write API. The page lists every registered phone with its MAC, vendor, model, paired SIP credential, claim state, and last provisioning fetch.

Register a phone

  1. Find the phone’s MAC address — on the label, the box, or the phone’s Status → Network screen.
  2. Click Register desk phone and enter:
    • MAC — colons, dashes, dots, or whitespace are accepted and normalized for you.
    • Vendorpolycom, yealink, cisco, or grandstream.
    • Model (optional) — e.g. VVX 450, T46U.
    • Label (optional) — e.g. Reception. Helpful when the fleet grows past a handful.
    • SIP credential (optional) — pair now, or pair later from the device row.
  3. Save. The response returns the provisioning URL — copy it from the confirmation dialog or from the device row at any time.
Each registration starts a 30-day claim window. If the phone never fetches its config in that window, the row flips to Expired and the URL stops working — rotate it (below) when the phone finally arrives.

Point the phone at the URL

The provisioning URL goes into the vendor’s redirect service — the phone already knows how to reach its vendor on first boot, and the vendor hands it your URL: Paste the provisioning URL against the phone’s MAC in that portal (supported vendors are also registered automatically on create when the vendor cloud accepts it — the dashboard response and audit log say which happened). Then factory-reset the phone so it boots through the redirect.
The provisioning URL carries a signed, single-use token bound to the MAC. Treat it like a password — anyone holding a live URL can provision the phone as your extension. Once the phone fetches its config the URL is spent and returns a generic refusal to everyone, including you.
If the URL leaked or was used on the wrong phone, run Rotate provisioning URL from the device row: it mints a fresh token, unlocks the fetch, and re-opens the claim window without touching the paired credential.

Pair with a SIP credential

A registered phone is inert until it is paired with a SIP credential — the extension it registers and calls as. Pair from the device row, or create the credential first under Voice → Extensions and pick it during registration. On the next boot after pairing, the phone pulls its config, authenticates, and registers against that extension. Re-pairing to a different credential takes effect the same way: rotate the provisioning URL and reset the phone.

Bulk import (CSV)

For a fleet rollout, click Bulk import on Voice → Desk phones and upload a CSV with a header row. mac and vendor are required; label and model are optional. Column order and case do not matter, and common header aliases are accepted.
The importer validates the header first — a missing mac or vendor column rejects the file before anything is written — then registers rows sequentially. The result panel reports registered / failed / skipped counts with per-line reasons: an invalid MAC or unknown vendor affects only that row; a duplicate MAC lands in the failed list with its line number. Fix the rejected lines and re-upload — already-registered rows report as duplicates, not errors. Bulk registration is rate-limited to 50 phones per hour per workspace, sized for exactly this rollout flow.

Remove a device

Delete a device from its row to revoke it: the SIP-edge association is soft-deleted, the provisioning URL dies, the vendor-cloud redirect entry is removed on a best-effort basis, and the action lands in the audit log. The phone keeps its last rendered config until it is reset — wiping and factory-resetting the handset is still on you. Re-registering the same MAC afterwards revives the row as a fresh device (new token, new claim window), so a torn-down phone costs nothing to bring back. Removing a device never touches the paired SIP credential.

API parity

Everything the dashboard does is available on the devices API under /api/v1/voice/devices. Base URL https://api.orbit.devotel.io; authenticate with a session bearer token or an API key. List and get accept owner, admin, developer, and viewer roles; create, update, rotate, and delete require owner or admin. CreatePOST /api/v1/voice/devices returns the device with its provisioningUrl:
macAddress accepts any common separator; claimExpiresAt (ISO 8601) overrides the default 30-day window, and null removes expiry for long-tail rollouts. A duplicate live MAC returns 409 — a MAC already in your workspace, or one registered to another workspace (contact support to transfer it). ListGET /api/v1/voice/devices?limit=50&cursor=<cursor> paginates by keyset cursor (limit 1–200, default 50; follow next_cursor). GetGET /api/v1/voice/devices/:id returns one device. UpdatePATCH /api/v1/voice/devices/:id changes label, model, sipCredentialId (set to null to unpair), notes, disabled, or claimExpiresAt. Disabling a device kills its provisioning URL without deleting the row. Rotate the provisioning URLPOST /api/v1/voice/devices/:id/rotate-provisioning mints a fresh token and unlocks the fetch after the first boot locked it. Returns 409 when there is nothing to rotate (the device has not been fetched yet).
DeleteDELETE /api/v1/voice/devices/:id soft-deletes the device and revokes the SIP-edge association. Phone-side fetch — the phone itself calls GET /api/v1/voice/provisioning/<mac>.xml?token=<token> (or .cfg), which is what the provisioning URL points at. It is unauthenticated by design — the booting phone owns nothing yet; the signed token in the URL is the credential. Every failure path returns the same generic 403, so the URL cannot be probed for valid MACs. Every device row also carries a directoryUrl: the remote corporate-directory (phonebook) feed for that phone. Yealink and Grandstream pick it up from their rendered config when the remote phonebook feature is on; for Cisco and Polycom, paste it into the vendor’s directory config by hand.

Screenshots

  1. Voice → Desk phones — device list with claim states.
  2. Register desk phone dialog (MAC, vendor, model, label, pairing).
  3. Provisioning URL confirmation after a successful registration.
  4. Bulk import result panel with per-line verdicts.

More