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

# Choosing a calling path

> Three ways to put a person on a live call through RevDesk: which to use, and why.

RevDesk gives you three ways to connect a person to a live phone call. They share a common security
baseline; they differ in **where the audio lives**, **whether the destination is locked by
construction**, and **whether you can add AI to the call**.

<Note>
  **On a phone (cellular, no browser), use the bridge path (C):** you call the API and RevDesk rings
  both parties, then bridges them. There is no proxy number you dial that forwards you onward — RevDesk
  always places the call. Paths A and B run the audio through the browser (WebRTC) instead.
</Note>

## What every path enforces (the baseline)

No matter which path you choose:

* **Scoped, single-use tokens.** Each calling token is issued for exactly one call and is invalidated when that call ends; it can't be reused.
* **You can only call *as* a number you own.** Caller ID is validated at issuance against your verified numbers.
* **Per-call attribution.** Every call is logged to your org + the issuing user + the from/to. Reconcile via `GET /v1/calls`.
* **Account guardrails.** A destination allowlist, a daily spend cap, a concurrency cap, and a max per-minute rate. This bounds the blast radius even if a token were leaked.

The paths differ in the **last mile**: whether the *destination* is merely scoped-and-bounded, or
**impossible to change** because the browser never dials at all.

## The three paths

### Path A: Call from your browser

**Available today.** Staff click **Call** and talk through their browser, no phone line needed. The
browser is handed a scoped, single-use token for that one call. Quickest to launch and proven-stable.

> Browser calling runs on **WebRTC**, the open web standard for live audio that lets a web page place
> and receive calls with no plugin and no phone line. Paths A and B are both WebRTC; path C uses a
> regular phone.

The destination is **declared, attributed, and guardrail-bounded**, but the browser is what dials, so
this path does not *lock* the destination by construction the way B and C do.

### Path B: Browser call, placed by RevDesk

**Available (beta).** Same in-browser experience, but the browser **never dials**. RevDesk places the
call and the browser simply *joins* it, using a room-join token from `POST /v1/room-token` and the
RevDesk browser SDK. Because the destination is set server-side, it **can't be changed by the client
or replayed to reach a different number**, and because the call lives in a room you can **add an AI
voice to the call** (mid-call assist, AI voicemail, AI follow-ups; on the roadmap).

### Path C: Bridge — connect on your own phone (cellular)

**Available today.** This is the path for a regular phone, no browser or SDK involved. Staff click
**Call**; *their own phone rings*; when they answer, the other party is already on the line. RevDesk
places both legs, so the destination is locked server-side and the other party only ever sees your
RevDesk number, never the staff member's personal number.

There is no proxy number to dial that forwards onward: a number anyone could dial can't authenticate
the caller, lock the destination, or mask caller ID per call. Placing both legs from the server is what
makes per-call attribution and number masking possible.

## Which should I use?

| Your situation                                                                                     | Use                                   | Why                                                                                                          |
| -------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Internal staff dialing; simplest, fastest setup                                                    | **A: Browser** (today)                | Proven, quick to ship; scoped tokens + guardrails are enough for trusted internal users.                     |
| Security- or privacy-sensitive / regulated (e.g. healthcare), and the person can answer on a phone | **C: Connect your phone** (today)     | Server-placed, hard destination lock, masked end-to-end. The available option that meets a strict bar today. |
| You want the hard lock **in the browser** (no phone), or you want **AI voicemail / follow-ups**    | **B: Browser, RevDesk-placed** (beta) | Same hard lock as C, but in-browser, and the path that enables AI on the call.                               |

<Note>
  **For a hard destination lock, use B or C.** Because RevDesk places the call, the destination can't
  be changed by the client and the token can't be replayed to reach a different number. Path A scopes
  and bounds the destination but does not lock it by construction.
</Note>

<Note>
  **AI on a live call** (inject an AI voice, AI voicemail, AI follow-ups) requires a RevDesk-placed
  path (B or C). The direct browser path (A) connects the audio straight from the browser, so there's
  no room for an agent to join. These AI capabilities are on the roadmap for B and C.
</Note>

## Reliability and UX tradeoffs

Beyond security, the paths differ in how the call actually behaves:

|                                  | A: Browser                            | B: Browser, RevDesk-placed                     | C: Connect your phone                 |
| -------------------------------- | ------------------------------------- | ---------------------------------------------- | ------------------------------------- |
| Audio path                       | WebRTC (data)                         | WebRTC (data)                                  | Cellular voice                        |
| Depends on the user's network    | Yes; needs a healthy connection + mic | Yes; needs a healthy connection + mic          | No; it's a normal phone call          |
| Connect latency                  | Instant (browser dials)               | Short delay (RevDesk places it, browser joins) | Short delay (RevDesk rings both legs) |
| Mic / browser permissions        | Required                              | Required                                       | None                                  |
| In-app controls (mute, transfer) | Yes                                   | Yes                                            | Limited (it's a phone call)           |
| AI on the call                   | No                                    | Yes (roadmap)                                  | Yes (roadmap)                         |

A and B are best when staff live in the app on a solid connection. C is the most resilient: it falls
back to the cellular network and needs no mic or browser permissions.

## Same surface, swap the path

Paths B and C expose the **same client surface**. Issue a token, attach a `callUpdate` handler, and
switching paths is close to a one-line change:

```ts theme={null}
import { RevDesk } from "@revdesk/sdk";
import { RevDeskRoom } from "@revdesk/webrtc";

const revdesk = new RevDesk({ apiKey: process.env.REVDESK_API_KEY! });

// Path B: browser joins a RevDesk-placed call
const { token, room_url, call_id } = await revdesk.webrtc.getRoomToken({ from_number, to_number });
const call = new RevDeskRoom({ token, roomUrl: room_url, callId: call_id });
call.on("callUpdate", render);
await call.join();

// Path C: bridge to a real phone. RevDesk rings connect_number; the destination
// still only ever sees from_number.
await revdesk.calls.dial({ from_number, to_number, connect_number });
```

## How they work

```mermaid theme={null}
flowchart LR
  subgraph A["A: Browser"]
    a1[Browser dials] --> a3[Called party]
  end
  subgraph B["B: Browser, RevDesk-placed"]
    b1[Browser joins] --> b2[RevDesk places the call] --> b4[Called party]
  end
  subgraph C["C: Connect your phone"]
    c1[Your phone] --> c2[RevDesk places both legs] --> c4[Called party]
  end
```

In **A**, the browser places the call itself. In **B** and **C**, RevDesk places the call and the
client only joins it, so the destination is fixed and can't be changed.

See [WebRTC security](/api-reference/webrtc-security) for the token model, caller-ID handling, the
guardrails, and concern-by-concern answers.
