RustPBX Basics: Call Forwarding — Always, When Busy, When No One Answers

M
Miuda Team
Building conversational AI tooling

Call forwarding is the most-requested feature after basic calling, and the one with the most edge cases: what counts as “busy”? What if the destination is another extension? What if the carrier rejects the forwarded leg? Here’s how RustPBX handles all of it.

Per-Extension Forwarding

Every extension has three forwarding knobs — mode, destination, and timeout:

ModeFires when
alwaysEvery incoming call, immediately
when_busyThe extension rejects with 486 Busy
when_not_answeredNo answer within the timeout (default 30s)

Set them in the console (Extensions → detail → Forwarding) or via the API:

curl -X PATCH http://<host>:8080/api/extensions/1001 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "call_forwarding_mode": "when_not_answered",
    "call_forwarding_destination": "1002",
    "call_forwarding_timeout": 25
  }'

The destination can be another extension or an external number (routed through your normal outbound rules, so billing and trunk selection apply).

Forwarding to a Busy On-Call Extension: Camp-On

Forwarding to when_busy hands the caller a busy tone — rarely what anyone wanted. For on-call destinations, busy-wait (camp-on) is usually better: the caller waits with hold audio, and the extension is re-dialed until free:

# in the forward route targeting the extension
[busy_wait]
enabled = true
max_wait_secs = 120
retry_interval_secs = 15
hold_audio = "sounds/hold-music.wav"

Non-busy failures and caller hangups exit the wait immediately.

Transfers: Blind, Attended, and Application

Once the call is up, transfers come in three flavors:

  • Blind (REFER) — the platform forwards the call; with 0.5’s hardened REFER handling, a B2BUA fallback bridges the legs when plain signaling can’t complete the transfer.
  • Attended (consult) — the agent calls the target first, speaks, then completes. Unanswered consults fail cleanly (409) instead of stranding legs.
  • Application handoff — if the call is inside an IVR or AI session, an inbound REFER preserves the application state on the new leg instead of dropping the caller back to a menu. An explicit resume event tells the flow where to continue.

Transfer context headers can be forwarded to outbound INVITEs per trunk (header_passthrough) when the far side needs them.

Forwarding to the Outside World

External destinations traverse the normal routing stack: match rules, LCR, trunk selection, billing. That means forwarded legs get recorded, rated, and traced like any other call — with the CDR carrying both the original and forwarded leg in its timeline.

Details: Extension Management and Routing, Trunk & Billing.

Get new posts by email

Deep dives on Rust telephony, contact centers and wholesale voice. No spam.

Thanks — you're on the list.

We use cookies for anonymous analytics to improve the site. Nothing is loaded until you accept. Privacy Policy