Skip to main content

Register your PBX on Orbit

Your PBX (Asterisk, FreeSWITCH, 3CX — anything that speaks SIP) connects to Orbit through a BYO-PBX trunk: an outgoing-direction entry whose host and port are the SIP endpoint Orbit registers against. Once it registers, the story never stops being told — when registration drops, the health surfaces tell you what changed and usually why. This page walks registration end to end: what your PBX needs, where the trunk lives in the dashboard, what the trunk URI actually carries, the 401-expand REGISTER exchange, config shapes for the three most common PBXs, and a checklist that tells you the setup is verified rather than assumed.

1 — Before you begin

Check these on the PBX side before you open the dashboard:
  • A publicly reachable SIP endpoint. Orbit’s registrar originates REGISTER requests from its edge, so your PBX must accept SIP traffic from the Internet — either a public IP directly on the PBX/SBC, or a port forward on your firewall that maps the chosen port (5060 is conventional; 5061 for TLS) to the PBX. An internal-only address cannot register.
  • SIP REGISTER support. Any standards-compliant PBX accepts REGISTERs on an inbound trunk; 3CX and most IP-PBXs expose this as a “trunk” or “SIP provider” template, and Asterisk/FreeSWITCH handle it natively.
  • Digest credentials to answer the challenge. Create the username/password pair on your PBX first; Orbit presents them when your registrar replies with 401 Unauthorized (the normal, expected first response).
The console asks for four things per outgoing trunk: One optional pair — authentication.username / authentication.password — carries the digest credentials your PBX issues. Credentials are encrypted at rest and never shown again in plaintext.

2 — Pick the direction

Orbit supports two trunk directions, and you pick one when you create the trunk:
  • Outgoing (this page) — Orbit registers a client of your PBX and uses the trunk as the dispatch path for calls that terminate into your equipment. This is the BYO-PBX trunk: host, port, transport, and optional digest.
  • Incoming — your PBX originates calls straight into Orbit. Your side sends INVITEs; Orbit never registers anywhere, so “readiness” there is a configuration verdict, not a REGISTER. See Connect a SIP trunk for the incoming half of the lifecycle.
Open Voice → SIP trunks in the dashboard — the page has tabs for Outgoing, Incoming, Routing, and Health. For the trunk this page is about, stay on Outgoing and click Add trunk. The dialog runs a pre-save probe against your endpoint (the same probe POST /api/v1/voice/sip-trunks/probe runs), so a broken path fails validation before it ever becomes a saved row. Keep this page about outgoing registration. The incoming shape is deliberately different (it authenticates each call by source IP, digest, or both), and mixing the two is the most common setup mistake.

3 — The trunk URI in detail

The trunk URI is the angle-dial destination Orbit builds from the trunk row: host:port over one transport. Pointers on each piece:
  • Host. The public hostname (or IP) of your PBX’s SIP endpoint. A hostname is strongly preferred over a raw IP because it survives an endpoint move — but the hostname must resolve publicly. The create handler rejects a non-resolvable host with a DNS-resolution error, and TLS additionally requires the host to match the certificate your PBX presents.
  • Port. Which port your PBX listens on. Convention is 5060 for UDP/TCP and 5061 for TLS; whatever you forward on the firewall must agree with what you save on the trunk.
  • Transport. udp, tcp, or tls. Prefer TLS where your PBX supports it: it encrypts the signalling path, and it sidesteps the NAT classes of failure that plague UDP (see Troubleshooting). The pre-save probe tests the transport you pick, so a TLS path that cannot complete the handshake fails the probe — and never becomes a broken saved row.
Credentials, codecs, concurrency caps, and failover are optional:
  • authentication — digest username/password Orbit presents when your registrar challenges.
  • codecs — up to 20 names in preference order (e.g. PCMU, PCMA, OPUS).
  • maxConcurrent — per-trunk concurrent-call ceiling, up to 2000.
  • failoverTrunkId — another trunk Orbit falls over to when this one drops registration.

4 — Registration vs. inbound acceptance

Registration is what turns the trunk into the dispatch path Orbit uses for outgoing calls: while status === "registered", routing decisions prefer it; when it drops, the console walks your designated failover trunk or lands on the platform default rather than failing outright. Registration is, mechanically, a digest handshake — the expected exchange on first contact:
  1. Orbit sends REGISTER to your endpoint.
  2. Your PBX answers 401 Unauthorized with a challenge.
  3. Orbit re-sends REGISTER with the credentials.
  4. Your PBX answers 200 OK, and the trunk is registered.
A 401 on the first attempt is normal — it is the challenge step, not an error. An errored registration is one that stalls at the challenge (wrong credentials), times out (unreachable endpoint), or never gets an answer (the firewall dropped it). What registration does not gate: inbound acceptance. Incoming calls from your PBX into Orbit are authenticated per call on the incoming-trunk side — never conflated with the REGISTER lifecycle of this trunk. An outgoing trunk whose registration lags still cannot dispatch new outbound calls (the dispatch gate refuses to launch on an unregistered verdict), but that is a dispatch decision, not a traffic-block on incoming calls delivered through other routes.

5 — Common setup shapes

The trunk row is identical across vendors; the difference is all in how your PBX accepts the REGISTER and which credentials it expects. Use these as templates — fill host, port, and credentials from the values you saved in the console.

Asterisk

Asterisk accepts inbound registrations via pjsip.conf. Declare an endpoint and an inbound registration entry, then point Orbit’s trunk at it:
pjsip.conf
Set transport=transport-tls if you saved transport: "tls" on the trunk; alpha-through-transport consistency matters because the REGISTER must arrive on the same transport your PBX is listening on. The trunk in Orbit carries authentication.username / authentication.password matching the orbit-trunk-auth block.

FreeSWITCH

FreeSWITCH accepts inbound registrations on a gateway-like inbound profile. Declare the digest user in the directory, and let the internal profile accept the REGISTER:
sofia profile (internal)
Point the Orbit trunk at the profile’s SIP IP and port (default 5060 UDP/TCP; 5061 TLS when you enable the TLS profile). If FreeSWITCH sits behind NAT, set ext-sip-ip and ext-rtp-ip on the profile so the advertised addresses are routable (the NAT failure described in Troubleshooting starts here).

3CX

In 3CX, create a SIP Trunk whose provider template is “Generic” and enter the registrar host/port the Orbit console shows you, the SIP transport you saved on the trunk, and the trunk’s digestUsername/digestPassword as the authentication pair. 3CX handles the register and the 401 challenge under the hood; your job is to make the transport and the firewall forward agree.
Outbound (MT) calls to the PSTN always egress through Orbit / Devotel’s wholesale softswitch — never through your trunk. Configuring a route that tries to move PSTN exit onto the trunk is rejected at dispatch; trunks deliver calls into your equipment, not out of the platform.

6 — Reading registration health

Every outgoing trunk shows registration status on every list card plus a health snapshot on the detail page. The snapshot threads through GET /api/v1/voice/sip-trunks/health — a ranked endpoint that buckets trunks by severity:
  • down — status === "unregistered": cannot carry outbound calls.
  • degraded — registered, but a failing streak is in progress (consecutiveFailures > 0), e.g., a REGISTER that keeps erroring on retry.
  • active — registered, streak-free.
  • unknown — no probe verdict stamped yet (new trunks, blipped probes).
Authenticate with your API key and call the health endpoint directly — it is a read of already-persisted diagnostics, so polling it never starts a probe:
cURL
A 200 OK returns the ranked rows plus the per-bucket tallies the dashboard tiles render. Needs attention sorts first: down before degraded before active before unknown, with the worst consecutive-failure streak on top inside each bucket. failingSince is the stamp the streak started at — null when the trunk is currently streak-free. From Node, the Node SDK covers trunk CRUD on orbit.voice.sipTrunks; reach this snapshot through the low-level orbit.request helper, which retries 429s and 5xx for you:
Node SDK
Validate your trunk before you save it — the dialog runs a pre-save probe — and re-run the probe from the detail page afterward if the registered status lags. Read the reason on the trunk row itself: lastRegistrationError carries the sanitized registrar response (DNS failure, timeout, challenge mismatch), no log dive needed.

7 — Troubleshooting

Work through these in order — they account for nearly every recorded registration failure. 1. NAT rewriting the source IP breaks TLS. A NAT between Orbit and your PBX rewrites source addresses between register attempts, and the TLS handshake then fails or stalls because the certificates and source addresses no longer agree with the session your PBX half-opened. Symptoms: the probe fails at “TLS handshake” or the health snapshot sticks degraded with a streak growing while signalling is reachable on plain TCP. Fix: put the PBX on a public IP (or use an SBC), or pin the outbound NAT to a single static egress — and prefer transport: "tls" end-to-end so the handshake is the only thing being rewritten. 2. Auth challenge loops. The registrar keeps answering 401 for every REGISTER, indefinitely, without ever issuing a 200 OK. Cause: the username/password on the trunk row does not match what your PBX accepted, or the PBX hashes the password against a different realm. Read lastRegistrationError for the recorded rejection; then align the authentication pair on the trunk (and re-run the test probe from the detail page) — rotations on the PBX side require a matching trunk update. Watch for the mirror-image trap on incoming trunks: a PBX-side password rotation also needs a trunk-side update in Orbit, or the next call burst returns a wall of 401s. 3. Transport mismatch. You saved transport: "udp" but the PBX listens only on TLS 5061 (or vice versa). Symptoms: immediate timeouts with nothing in the PBX logs — the request never arrives. Fix: match the trunk’s transport to the transport your PBX profile actually binds; the pre-save probe fails loudly on exactly this before it becomes a saved row. 4. Timeout signatures. A timeout on the REGISTER is almost always one of three things: the host does not resolve (DNS failure — recorded verbatim), the firewall dropped the SIP port (allow UDP/TCP/TLS 5060/5061 from Orbit’s edge addresses), or the port forward points to the wrong internal address. Symptom check: if the PBX logs show no arrival, the failure is reachability; if logs show arrival but no 200 OK, the failure is auth or transport. 5. Incoming-direction confusion. If the symptom is “incoming calls rejected”, it is not registration — read the trunk’s lastCallVerdictReason (auth failure, caller-id mismatch, routing rule violation, billing hold) and follow the incoming-trunk diagnostics in Connect a SIP trunk.

8 — Verified setup checklist

Run this against your actual trunk before calling it done:
  • The PBX has a publicly reachable SIP endpoint (public IP or port forward), and your firewall allows the SIP port from Orbit’s edge.
  • Digest credentials exist on the PBX and match the authentication pair on the trunk.
  • The trunk is saved as outgoing — not incoming — under Voice → SIP trunks → Outgoing.
  • Pre-save probe returned reachable: true with the expected status.
  • After save, the trunk row reads status: "registered" and severity: "active" on the health snapshot.
  • If your PBX negotiates TLS, the trunk carries transport: "tls" end to end — probe-verified.
  • One outbound test call completed media end to end (POST /api/v1/voice/sip-trunks/{id}/test-call).
  • A failoverTrunkId is set on trunks that carry traffic, so a dropped registration hands calls to a backup instead of failing outright.
  • The health endpoint is polled into your monitoring, alerting on counts.down > 0 or counts.degraded > 0.
This page is the register-focused companion to two siblings — share the same diagnostics rather than re-reading them here:
  • Connect a SIP trunk end to end — the full lifecycle (direction choice, one-time incoming credentials, readiness verification, DID routing, monitoring) that this page’s registration piece slots into.
  • Connect a SIP trunk (BYOC) — the broader bring-your-own-carrier/PBX guide, including RTP/media and codec drills that apply after registration is healthy.
  • SIP trunks troubleshooting — the recorded-cause ledger both guides link to.