Worked SIP credential samples
SIP credentials are usually the first calls a contact-center integration makes — they register each agent’s softphone or desk phone. Copy a request as written, substitute your own ids, and compare the response envelope. Successful writes return{ data, meta }; failures return the { error, meta } envelope. The retry-vs-surface matrix for every class sits at the bottom of this page.
A credential owns a softphone registration on the inbound SIP edge: the device REGISTERs against sip.orbit.devotel.io, inbound calls ring it, and outbound usage (if enabled) is tracked against the credential. The samples below pair cURL with Node — reads use a raw fetch; the SIP-credential surface has no typed Node SDK resource yet, so the write tabs use the orbit.request escape hatch pattern from the API recipes.
Page the credentials
GET /api/v1/sip-credentialslimit defaults to 25 and caps at 200; a value above the cap is silently clamped, not rejected. When meta.pagination.has_more is true, pass meta.pagination.cursor back as the cursor query parameter for the next page.
Request
sip_server, sip_realm, ports) so a per-row read is not required to configure a device. The plaintext password is never in a list row.
Create a SIP credential
POST /api/v1/sip-credentialslabel is the only required field; it is lowercased and slugified into the SIP username, which stays stable across password rotations. This example wires a front-desk handset: an extension, a fixed caller ID, recording-on, and an IP allow-list.
Request
sip_server + username + the one-time password; the create response is the only place the password appears. defaultCallerIdE164 is ownership-checked — a number your organization does not own is rejected with a 403 (folded into the matrix below, since “pick a number you own” is obvious from the message).
Rotate a password
POST /api/v1/sip-credentials/{id}/rotateForce-unregister a device
POST /api/v1/sip-credentials/{id}/unregisterenabled: false. Use this for a stolen phone or a sticky NAT binding.
Request
Errors worth branching on
These failures cover the create, rotate, unregister, and read calls above plus the update (PATCH) and delete calls on the same page. Each block is a full{ error, meta } envelope as the API returns it, and the matrix at the bottom answers retry vs surface for the same classes. For the platform-wide decision table these branches plug into, see the error handling guide.
403 — scope or caller-id ownership
403
403 on create or rotate means the key lacks the write scope — developer and viewer roles can read credentials, and admin or owner is required to create or modify, so branch on the role and surface instead of retrying. The same 403 shape also fires when defaultCallerIdE164 names a number your organization does not own — the call is rejected before the credential is created.
409 — duplicate label or extension
409
409 CONFLICT — pick a new label or rotate the existing credential instead of blind-retrying. This is the same branch a teams-client codes on duplicate name: the client decides whether to label the device differently or PATCH the existing row.
404 — stale or foreign id
404
404 on get/update/rotate/unregister/delete means the sipcred_* id does not exist in your organization (or was soft-deleted) — re-list credentials and branch on the current id rather than retrying the stale one.
60-second retry matrix
Provision a SIP trunk and take the first call
A SIP credential is Orbit’s per-device trunk identity: it authenticates one user agent at the SIP edge, holds its registration, and carries the outbound controls you set on it. The worked chain below takes one device from an empty organization to a registered, calling credential, then rotates it without dropping the device. (Interconnecting a whole PBX rather than a device? Start from Connect a SIP trunk end to end instead; the credential chain below is the device-side equivalent.)1. Issue the credential
POST /api/v1/sip-credentialsusername at sip_server (digest realm sip_realm), TLS on 5061 with SRTP mandatory. The password field appears exactly once, in this response; save it before the response scrolls away.
Request
username, the one-time password, sip_server on port 5061 (TLS), and sip_realm where the client asks for a realm. That is the whole SIP account; there is nothing else to wait for.
The optional userId body field links the credential to a user in your
organization — its value reads back as user_id on every response row.
When an inbound call rings a linked credential, that user’s phone also
receives a native incoming-call push (PushKit on iOS, high-priority FCM
on Android) that wakes the OS call UI even when the app is locked or
force-quit, in addition to the organization-wide ring alert. A userId
that is not a live member of the organization is rejected with
403 FORBIDDEN on both create and update; userId: null on a PATCH
unlinks and restores alert-only behaviour. Unlinked credentials behave
exactly as before. Detail:
Link a SIP extension to a user.
2. Confirm the reachable state
GET /api/v1/sip-credentials/{id}registered flip to true with a fresh last_register_at; a 401 loop on the device means the password was mistyped or already rotated (see the failure list in SIP credentials provisioning).
Request
3. Register and originate
With the binding live, the device originates outbound calls through the same registration: dial any destination from the user agent and the edge applies the credential’s caller-ID mode, spend cap, and country block list. No further API call is needed to place the call from the device itself. To originate from the API side instead, or to land a billable test call on a PBX trunk, follow SIP trunk first call walkthrough: it runs the pre-save probe, saves the trunk with the probe verdict, and confirms media end to end withPOST /api/v1/voice/sip-trunks/{id}/test-call. On the credential side, the equivalent confirmation is the read above: keep registered: true and a fresh last_register_at (an OPTIONS qualify from your SBC keeps the Contact fresh between calls).
4. Rotate with an overlap window
Zero-downtime rotation is two calls against two credentials: issue the replacement, then give the old credential a futureexpiresAt (its scheduled disable time) so both passwords authenticate during the change window. Devices reconfigured onto the new credential register immediately; devices still on the old one keep working until expiresAt passes.
Issue the replacement
DELETE it then, or leave it expired until you do. For an immediate single-credential password change (lost device, leaver) use POST /{id}/rotate instead: the username stays, the old password dies at once.
Keep going
- SIP credentials provisioning: the digest handshake, the limits, and device-class worked examples.
- Connect a SIP trunk (BYOC): RTP, codecs, and inbound auth when the far end is a PBX or carrier.
- SIP trunk first call walkthrough: probe, save, verify, and the billable test call.