> ## 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.

# Make your first outbound PSTN call: SIP trunk or browser softphone

> From zero to a live PSTN call in one sitting — buy a voice number, pick SIP trunk or browser softphone, dial a real destination, and read the call lifecycle from ringing to completed.

# Make your first outbound PSTN call

Two paths turn a new Orbit account into a phone that dials the PSTN:

* **Option A — register a SIP trunk** with your own PBX or softphone
  software, and let API-origin calls dial out over it.
* **Option B — the browser softphone**, where an agent dials straight
  from a web page with no SIP client to install.

Both end at the same place: an outbound PSTN call with a readable
lifecycle (`ringing` → `answered` → `completed`). This guide walks either
path end to end and links the deep-dive page for the path you pick.

<Note>
  Every outbound leg terminates through the Devotel softswitch. A trunk
  you register here is one origin surface; the termination path stays on
  Orbit's own network either way.
</Note>

## 1. Prerequisites

Which prerequisite applies depends on the path:

* **Option A (SIP/trunk):** a SIP-capable PBX (FreeSWITCH, Asterisk,
  3CX) or a desktop SIP client (for example MicroSIP or Linphone), plus
  inbound SIP-credentials you mint on the account.
* **Option B (browser softphone):** an HTTPS page and a browser with a
  microphone grant — the same rules the
  [browser softphone guide](/guides/voice-softphone-browser-calling)
  lists in full.
* **Either path:** at least one voice-enabled DID in the account to
  present as caller ID, and an API key with voice scope if you dial via
  the API.

## 2. Buy a voice-capable number

If the account has no DID yet, work through
[Buy and provision numbers](/guides/buy-numbers) — search inventory
with `capabilities=voice` (or `sms,voice` when messaging will share the
number), purchase, and poll the order until the line reports
provisioned:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/numbers/available?country=US&type=local&capabilities=voice" \
  -H "X-API-Key: dv_live_sk_..."
```

Keep the E.164 of the purchased number — it is the `from` on every
dial below, and it is the only caller ID the outbound surface accepts.

## 3. Option A — register a SIP trunk

This path connects your own phone system to Orbit. The full lifecycle
(direction choice, probe-before-save, credential capture, routing,
monitoring) is a nine-step walkthrough in
[Connect a SIP trunk](/guides/sip-trunk-setup); the short version for a
first call:

1. Create the trunk with the carrier-facing details:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/sip-trunks \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "HQ PBX",
    "host": "pbx.example.com",
    "port": 5060,
    "transport": "udp"
  }'
```

2. Register the device that will originate calls (your PBX, or a SIP
   client on an agent's desk) against the SIP edge host shown in
   **Settings → SIP trunks**, using the digest or IP-allowlist auth the
   trunk is configured with.

3. Skip to [section 5](#5-dial-a-single-pstn-call) — once the originating
   surface exists, the dial step is identical to Option B.

A trunk that fails to register never carries the first call — run the
pre-save probe (`POST /api/v1/voice/sip-trunks/probe`, exercised in
[sip-trunk-setup](/guides/sip-trunk-setup#step-2-create-an-outgoing-trunk))
and it names the failing phase (DNS, connect, or REGISTER) instead of a
generic rejected call.

## 4. Option B — the browser softphone

The no-install path: mint a short-lived credential, connect the client,
dial. The full guide is
[Set up the browser (WebRTC) softphone](/guides/voice-softphone-browser-calling);
on a first call you need three moves.

1. Mint a token:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/softphone/token \
  -H "Authorization: Bearer dv_live_sk_..."
```

2. From your own page, mount the SDK softphone and connect — a minimal
   HTML page:

```html theme={null}
<!doctype html>
<button id="connect">Enable microphone</button>
<input id="to" placeholder="+14155550100" />
<button id="dial">Dial</button>

<script type="module">
  import { OrbitSoftphone } from "https://cdn.jsdelivr.net/npm/@devotel-orbit/web";

  const softphone = new OrbitSoftphone({
    apiBaseUrl: "https://api.orbit.devotel.io",
    apiKey: "dv_live_sk_...", // serve from your backend, never commit it
  });

  document.getElementById("connect").onclick = async () => {
    await navigator.mediaDevices.getUserMedia({ audio: true });
    await softphone.connect(); // mints token, publishes mic
  };

  document.getElementById("dial").onclick = () =>
    softphone.dial(document.getElementById("to").value);
</script>
```

3. Dial from the browser, or call the endpoint directly once the client
   is connected:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/softphone/dial \
  -H "Authorization: Bearer dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155552671", "from": "+16572262362" }'
```

Credentials live 60 minutes — re-mint before `expiresAt` instead of
recycling. The browser-fallback reality and the inbound decision (DNIS
→ queue or SIP routing for inbound rings) live in the
[softphone guide](/guides/voice-softphone-browser-calling).

## 5. Dial a single PSTN call

With either origin surface registered, the dial step is one API call —
`POST /api/v1/voice/calls`. Pass the bought DID as `from` and any PSTN
destination as `to`; a `record: true` flag captures the audio for the
post-call read:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/calls \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "from": "+16572262362",
    "record": true
  }'
```

The `2xx` response returns `data.id` (`call_…`) — the handle every later
step uses. Options `answer_url`/`staticVerbs`, AMD, and metadata-level
bookkeeping are at
[Program an outbound voice call](/guides/programmable-voice-call); for a
first call there is nothing to configure beyond `to` and `from`.

## 6. Read the lifecycle states

A call moves `ringing` → `in_progress` → a terminal `completed` on
answer (or `failed` / `no-answer` on a declined or unanswered ring).
Poll the record:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/voice/calls/call_9f2a1c \
  -H "X-API-Key: dv_live_sk_..."
```

…or subscribe to `call.completed` / `call.failed` webhooks under
**Settings → Webhooks** and [verify the delivery
signature](/guides/verify-webhook-signatures). The Voice calls page in
the dashboard lists the same progression per call; the full state map
and webhook payloads live in
[programmable-voice-call](/guides/programmable-voice-call#4-track-progress).

## 7. Common errors

These cover the failures a first outbound call hits in the wild:

| Symptom                                          | Cause                                                                                                  | Fix                                                                                                                                                                                                                                                                               |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`/`407` on REGISTER, or trunk `unregistered` | SIP auth fails: wrong register username/password, or a digest challenge answered with a stale password | Re-check the credentials the carrier issued (Option A trunk) or the minted SIP credential (desk client). On Orbit-side incoming trunks, rotate the digest password — the plaintext is shown exactly once at create.                                                               |
| Call connects, then one-way or no audio          | Codec mismatch or SRTP posture                                                                         | On the trunk, drop to the codecs your carrier lists; on softphone credentials, SRTP is mandatory and an RTP-only client never establishes audio. See TLS/SRTP posture in [sip-trunk-setup](/guides/sip-trunk-setup#step-4-tls-and-srtp-posture).                                  |
| Outbound rejected right at originate             | Outbound blocked                                                                                       | Emergency-shaped dials are rejected (`EMERGENCY_CALLING_NOT_SUPPORTED`). Otherwise the trunk's routing rules (a destination blocklist) or the account's spend cap and quiet-hours gate stopped it, or no trunk registered at all — the error returned on the dial names the gate. |
| `403 Organisation does not own phone number …`   | `from`/`callerIdNumber` is not a DID the account owns                                                  | Buy or port the number first; outbound CLI can only be an owned DID.                                                                                                                                                                                                              |
| Register probe never succeeds                    | DNS or firewall on the SIP edge                                                                        | Probe before save (`POST /api/v1/voice/sip-trunks/probe`) names the failing phase explicitly.                                                                                                                                                                                     |

SIP failures past this short list are covered in
[Troubleshooting: SIP trunk down or calls failing](/channels/voice/sip-trunks-troubleshooting);
lifecycle outcomes that look like (`no-answer`, busy, unreachable) map
in [programmable-voice-call](/guides/programmable-voice-call#7-failure-modes).

## Where to go next

* **Program every call** — answer\_url verbs, AMD, recordings,
  transcripts: [Program an outbound voice
  call](/guides/programmable-voice-call).
* **Run the trunk in production** — failover, health snapshot, route
  quality: [Connect a SIP trunk](/guides/sip-trunk-setup).
* **Give agents the full softphone** — inbound routing, mobile push,
  SDK events: [Browser (WebRTC)
  softphone](/guides/voice-softphone-browser-calling).
