> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: outbound calls rejected with SBC_UNAVAILABLE

> A 503 SBC_UNAVAILABLE on POST /api/v1/voice/calls or on a dialer-dispatched outbound leg means the platform could not hand the call to the session border controller that terminates it. Work the debug ladder to find which side owns the cause, then use the fix-vs-retry table to separate edit-and-re-issue from retry-with-backoff.

# Troubleshooting: outbound calls rejected with SBC\_UNAVAILABLE

`SBC_UNAVAILABLE` (HTTP 503) is the refusal the voice API returns when it
could not hand an outbound call to the session border controller (SBC)
that terminates it. Every outbound call leaves Orbit through an SBC,
either on your own SIP trunk or on the platform's wholesale routing, so
the cause lives on one of three sides: your trunk's SBC, the upstream
carrier, or a transient platform blip. This page walks the ladder that
finds which, and tells you when a retry helps and when only a config
change does.

## What you see

* **API dispatch.** `POST /api/v1/voice/calls` (and the softphone dial
  that goes through it) answers `503` with the code in the error
  envelope:

```json theme={null}
{
  "error": {
    "code": "SBC_UNAVAILABLE",
    "message": "Devotel SBC is not available. Retry in a moment or contact support.",
    "status": 503,
    "docs_url": "https://docs.orbit.devotel.io/errors/SBC_UNAVAILABLE"
  },
  "meta": { "request_id": "req_01hxyz", "timestamp": "2026-10-16T09:12:44.210Z" }
}
```

Copy `meta.request_id` now; it is the anchor support traces by.

* **Dialer-dispatched outbound legs.** Campaign and journey calls do not
  return the 503 to you directly. The leg lands as `failed` in the
  campaign's call results, and the same row shows in the Voice call log
  (filter `status=failed`, `direction=outbound`, see
  [Voice call logs](/guides/voice-calls-call-logs)).
* **Webhook.** Each rejected leg also arrives as a `call.failed` event on
  your voice webhook endpoint (see
  [Webhook events](/webhooks/events)), so an integration that watches
  `call.failed` sees the refusal even when no operator is looking at the
  dashboard.

On a softphone dial the operator sees a short "try again in a moment"
notice rather than the raw code; the envelope above is what your API
integration receives.

## Causes

Work top-down. The first three are yours or your carrier's; the last is
the platform's.

1. **Your trunk's SBC is unreachable.** The target SBC is down, or a DNS
   record or IP allow-list changed on your side (a BYOC firewall rule, a
   rotated egress allow-list) so the platform edge is refused. This is
   the most common cause on customer-managed trunks.
2. **Carrier-side outage on the upstream route.** The SBC answers but the
   carrier's next hop is down; failures arrive in a burst that matches
   the carrier's maintenance window rather than any change of yours.
   Check your carrier's status channel and the
   [Orbit status page](https://status.orbit.devotel.io).
3. **TLS or profile mismatch after a trunk edit.** A certificate that no
   longer chains, a subject name that no longer matches the host, or a
   codec/transport profile the carrier rejects at INVITE time. Rejects
   that begin exactly when you saved a trunk edit are this until proven
   otherwise; the TLS pass lives in
   [SIP trunk troubleshooting](/troubleshooting/sip-trunk#tls-and-srtp).
4. **A transient platform media blip.** The media plane that bridges your
   call onto the SBC occasionally loses signaling connectivity for
   seconds at a time, and the API answers the same clean 503. This class
   self-heals in moments and is the one retry-with-backoff is for; if it
   persists beyond a few minutes it is an incident, not a blip.

`SBC_UNAVAILABLE` means the platform never placed the call on the wire.
Refusals from the pre-send checks (emergency, destination, caller
identity) return their own 4xx codes instead; see the
[voice pre-send gate chain](/concepts/voice-pre-send-gate-chain) for that
ladder.

## Debug ladder

Run these in order; each step narrows which cause above you are in.

1. **Read the trunk record.** `GET /api/v1/voice/sip-trunks/:id`, or
   **Settings → Voice → SIP trunks** in the dashboard, returns `status`,
   `lastRegistrationError`, and `lastRegistrationCheckAt`. A `status`
   other than `registered` with a named `lastRegistrationError`
   (`DNS resolution`, `TCP/TLS connect`, `401`, `488`) puts the fault on
   your trunk's path; fix the named cause per the
   [SIP trunk runbook](/troubleshooting/sip-trunk).

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/voice/sip-trunks/trunk_abc123" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

2. **Compare timestamps.** Line the first `call.failed` event up against
   the trunk's last config change and its `lastRegistrationCheckAt`.
   Failures that begin the minute a trunk edit saved point at cause 3;
   failures that begin with no change of yours point at cause 1 or 2.
3. **Reproduce with one manual call.** Place a single call by hand, from
   the softphone or one `POST /api/v1/voice/calls`. If the lone call fails
   exactly like the dialer's burst, the fault is per-call reachability or
   config, not dialer concurrency. If only the dialer fails while manual
   calls pass, you are on a capacity gate instead, and the capacity
   section of the [SIP trunk runbook](/troubleshooting/sip-trunk) is the
   page you want.
4. **Prove the path with an inbound test.** If the trunk also carries
   inbound calls, place a test call into it. Inbound succeeding while
   outbound fails narrows the fault to the outbound route or profile;
   both directions failing puts it on reachability (cause 1).

## Fix vs retry

The code alone does not tell the two apart; the failure pattern does. A
deterministic config fault never clears on retry, and retrying it burns
dialer attempts against a dead setting. A transient outage clears on its
own and rewards spaced retries.

| Signal | Class | Action |
| - | - | - |
| Every call fails, starting at the minute of a trunk edit | Deterministic config fault | Revert or correct the edit (host, port, transport, certificate, codec profile), re-test the trunk, re-issue the call once |
| Every call fails, `status` not `registered`, named `lastRegistrationError` | Deterministic reachability fault | Fix the named cause on your side (DNS, firewall allow-list, credentials), re-test, re-issue once |
| Failures in a burst on a trunk that was healthy; carrier reports maintenance | Carrier-side outage | Hold new traffic or fail over to another trunk; retry queued work with backoff |
| A small share of calls fails for seconds at a time, then passes again | Transient platform blip | Retry with exponential backoff and jitter, honoring any `retry_after` the envelope carries; never a tight loop |
| Failures persist past your retry ceiling, or the [status page](https://status.orbit.devotel.io) shows an incident | Incident | Stop retrying and escalate with the bundle below |

Two rules keep this safe:

* **Never retry a deterministic fault as-is.** An unchanged re-issue of a
  refused call returns an unchanged 503, and a tight loop can trip
  carrier-side rate limits that turn a misconfiguration into a block.
  Edit, re-test the trunk, then re-issue once. For API-originated calls,
  send an `Idempotency-Key` on the re-issue so a retry racing the
  recovery cannot originate the call twice (see
  [Idempotency and billing gates](/troubleshooting/idempotency-and-billing-gates)).
* **Back off the transient class, do not flat-retry it.** Spaced attempts
  ride a blip out; a tight loop turns the blip into a backlog.

## Bring Your Own Carrier trunks

If the trunk is **customer-managed** (your SBC, your carrier contract),
the platform fails closed: a trunk it cannot reach is refused with this
code, except where your configured failover chain or the dispatch
fallback described in the
[SIP trunk runbook](/troubleshooting/sip-trunk) routes around it.
Everything on your side of the path (the SBC, its DNS, its firewall
allow-lists, its certificates) is yours to fix; work the ladder above and
re-test. Note the split with caller identity: an INVITE whose caller-id
is outside the trunk's `allowedCallerIds` list is a 403
`VOICE_CALLER_ID_REJECTED`, not this 503 (see the
[FAQ entry](/reference/faq#why-did-my-caller-id-rewrite-get-rejected-on-my-own-sip-trunk-with-voicecalleridrejected)).

If the trunk is **platform-managed**, the same 503 pages Devotel on-call
automatically; there is nothing to edit on your side and no retry budget
to wait out before opening a ticket. Either way, include the bundle
below so the first response is not a request for more data.

### The bundle support needs

* The **`request_id`** from `meta.request_id` on the 503 envelope, or from
  the failed row in **Insights → Logs** for dialer-dispatched legs.
* The **`trunk_id`** (`trunk_…`) the call was placed through, or "platform
  default" when you do not run your own trunk.
* The window: first and last `call.failed` timestamp, and whether any
  trunk or carrier change preceded it.

## What not to do

* **Do not loop the retry on a config fault.** An unchanged re-issue
  changes nothing; back off, fix, re-issue once.
* **Do not edit the trunk while a burst is in flight.** Changing host or
  credentials mid-burst mixes two failure populations and makes the
  timestamp comparison in the ladder meaningless.
* **Do not rotate carrier credentials to chase a blip.** A rotation only
  answers a `401`-class `lastRegistrationError`; on an unreachable SBC it
  adds a second variable.

## When to escalate

Open a support ticket when you have worked the ladder, re-tested the
trunk, and the 503 persists past your backoff window, or whenever a
platform-managed trunk repeats the refusal. Attach the bundle above plus
your organization ID (**Settings → Organization**). If the trunk is
customer-managed and the ladder points past your edge, take the
`lastRegistrationError` text and the timestamps to your carrier; the
platform records what it saw on its side of the handshake, and that is
the evidence your carrier's SBC team needs.

## See also

* [Troubleshooting: SIP trunk registration, health, failover, and capacity](/troubleshooting/sip-trunk)
  — the registration, TLS, and capacity deep dive this page defers to.
* [SIP trunks in the dashboard](/channels/voice/sip-trunks-troubleshooting)
  — the settings table, route-quality view, and auth ledger.
* [VOICE\_GATEWAY\_ERROR at call-send](/troubleshooting/voice-gateway-error)
  — the sibling refusal when the voice gateway, not the SBC path, fails.
* [Voice pre-send gate chain](/concepts/voice-pre-send-gate-chain) — when
  the refusal is a 4xx gate before the SBC rather than this 503.
* [Why did my caller-ID rewrite get rejected on my own SIP trunk with `VOICE_CALLER_ID_REJECTED`?](/reference/faq#why-did-my-caller-id-rewrite-get-rejected-on-my-own-sip-trunk-with-voicecalleridrejected)
  — the trunk-side caller-identity refusal that is a 403, not a 503.
* [Error codes reference](/reference/error-codes) — the full envelope
  catalogue.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.