# SIP trunks for an existing PBX or SIP application

Apply the [authorization policy](../SKILL.md#authorization-and-working-style) to every step,
including local files, sends, paid features and test calls. Proceed within existing authority;
ask only for missing decisions or authority, or report blocked steps when unattended.

Read this only when connecting an external system as a SIP trunk. Employee desk phones and
softphones use [devices](devices.md). A trunk has no employee owner or extension; do not create
users, devices or a hosted callflow for it. The same native trunk appears in the Control panel’s
**SIP Trunking** app. Hosted users and trunks can coexist in one account.

Requires CLI 0.7.0 or later and an account admin. Check `rinzo version` and `rinzo schema trunks`.
If an older CLI is installed, upgrade with the install script and refresh `rinzo skill install`.
The account’s existing calling restrictions and caller-ID policy still apply.

## Discover and choose authentication

```sh
rinzo trunks list
rinzo numbers list
rinzo account show
```

Use the supplied name, authentication method, incoming phone numbers (if any), and account
number for outgoing caller ID; resolve only missing details under the authorization policy.
Inspect current number destinations before making changes.

- **Username/password:** generated credentials; the PBX normally registers to receive calls.
  A fixed incoming destination is optional when the PBX does not register.
- **IP:** one public source IPv4 address. No registration or password. Incoming calls go to the
  same address; a different incoming host is not supported in this mode. Behind NAT, use the
  public egress address and arrange incoming SIP/media forwarding at the PBX network.

```sh
rinzo trunks create --name "Office PBX" --auth password --credentials-file office-trunk.json
rinzo trunks create --name "Voice application" --auth ip --ip 203.0.113.25
rinzo trunks credentials TRUNK_ID --credentials-file connection.json
```

Use the returned trunk ID for later commands. Credential files are private (0600); existing files
require `--force` to replace. Ordinary reads, including `trunks credentials`, hide passwords;
`--show-secrets` reveals them. Keep secrets out of chat, logs and shell arguments. To supply a
password, use `--password-file PATH`. Configure the external system through its supported setup
interface; creating the Rinzo trunk does not configure that PBX automatically.

Connection details include the account realm, SIP proxy, authentication and incoming destination.
Use the account realm as the SIP domain and the returned proxy (normally `sip.rinzo.tel`). TLS
signaling uses port 5061; UDP/TCP use 5060. Fixed incoming destinations use UDP. Registered-contact
delivery follows the registration’s transport. TLS signaling alone does not prove encrypted audio;
do not copy employee-device SRTP requirements into a trunk setup. Start with G.711 PCMU/PCMA,
RFC 2833 DTMF, and SIP ALG disabled. Media uses UDP 16384–32768. For a firewall allowlist, allow
signaling and media from both Rinzo SIP servers, listed at https://rinzo.ai/sip-addresses.json
(`sip.rinzo.tel` moves between them on failover).

## Route numbers and adjust settings

```sh
rinzo numbers assign +16045550123 --trunk TRUNK_ID
rinzo trunks get TRUNK_ID
rinzo trunks update TRUNK_ID --caller-id +16045550123 --codecs PCMU,PCMA
rinzo trunks update TRUNK_ID --delivery-host pbx.example.com --delivery-port 5060
rinzo trunks update TRUNK_ID --delivery-host ""
```

`--delivery-host` is for password trunks; an empty string restores registered-contact delivery.
Other options include `--number-format e164|1npan|npan|username`, `--timeout SECONDS`,
`--caller-name NAME` and `--failover +16045550124` (or a `sip:user@host` URI). Empty caller-ID,
codec and failover values clear those options. New trunks use processed media; editing preserves
existing advanced and per-number settings unless explicitly changed.

To move a number that already routes to a hosted callflow or another trunk, follow the skill's
four steps: `numbers list`, `numbers unassign NUMBER`, `numbers assign NUMBER --trunk TRUNK_ID`,
then check `destinations`. Rinzo does not stop a callflow and a trunk listing the same number; the
assign result's `next` and `numbers list` say when that happens and how to keep one
(`numbers unassign NUMBER --callflow ID` or `--trunk ID`). Unassigning keeps the number in the
account. `trunks numbers assign|unassign` also supports repeatable `--number` for one trunk. A
trunk can be outbound-only with no incoming numbers assigned; outgoing caller ID must still
satisfy the account’s policy.

Updates use native HTTP preconditions. A 412 means another session changed the document: read it
again and review the intended change. Never automatically overwrite or replay a failed write.

## Verify and maintain

```sh
rinzo trunks status TRUNK_ID
rinzo trunks calls TRUNK_ID --since 1h --limit 20
rinzo trunks rotate-password TRUNK_ID --credentials-file replacement.json --yes
rinzo trunks delete TRUNK_ID --yes
```

Read back after changes. Registration is `registered`, `not_registered`, or
`registration_unavailable`; IP/fixed-destination trunks report `registration_not_required`.
These states do not prove working calls or audio.
Make only authorized test calls to check answered outgoing calls, incoming calls to assigned
numbers, two-way audio and keypad tones; report unperformed checks pending. `callflows simulate`
covers hosted routing, not the external PBX or trunk call path.
History defaults to seven days, is limited to the selected trunk, and accepts windows up to 31 days.

Password rotation requires updating the external system; scope rotation and that update to
the trunks and systems covered by existing authorization, including standing approval. Disabling rejects new calls without
hanging up existing calls; IP changes also need the SIP edge’s normal refresh (allow up to 90 seconds).
Deleting a trunk unassigns its numbers but **retains them in the account**; it does not release them.
Preserve unrelated trunks and hosted routes. Report which configuration checks passed and which
real-call checks were actually completed.
