Skip to content

docs: add outbound calling guide - #660

Open
Devon-White wants to merge 41 commits into
mainfrom
Devon/outbound-calling-guide
Open

docs: add outbound calling guide#660
Devon-White wants to merge 41 commits into
mainfrom
Devon/outbound-calling-guide

Conversation

@Devon-White

@Devon-White Devon-White commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add a comprehensive outbound calling guide covering the Calling API, AI agents, Compatibility API, and Relay
  • consolidate the Vapi inbound and outbound setup guides into one integration guide
  • redirect the former Vapi guide URLs to the consolidated page

Validation

  • yarn fern-md-check — all 2,829 MDX files valid
  • git diff --check
  • yarn fern-check — blocked by Fern FDR returning HTTP 403 during the remote missing-redirects check

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Devon-White and others added 21 commits September 8, 2026 09:24
…rface

Group by hand-off vs. stay-on-the-call control instead of one section per
API, cover the Server SDK's REST client (Python + TypeScript) and the
Browser SDK, add a themed SVG lifecycle diagram for human readers with the
mermaid source kept for the LLM export, and drop the Compatibility API and
cXML from this guide's scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…view

Reduce the up-front load on a first-time reader:

- cut the duplicated framing so the intro, the concept prose, and the API
  table each say one thing instead of three
- move the announcement SWML next to the dial request it feeds, removing the
  forward jump to a later section
- collapse the inline swml and custom_variables path into an accordion
- move the trial-mode and international constraint into a Note
- drop the 422 paragraph that repeated the first troubleshooting accordion
- retitle sections to name the outcome rather than the pattern

Add a "Place an outbound call" card to the Voice overview's Get started grid.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Move Examples ahead of progress tracking and troubleshooting so a new
reader reaches working code before failure cases, and close the guide
with Next steps cards.

Replace the bold pseudo-label paragraphs and bullets with prose, drop
the H4s nested inside tabs (their anchors were unreachable and absent
from the TOC), and use one naming scheme for tab and code block titles
so the REST/Relay choice follows the reader down the page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Call Fabric" names the platform, not a kind of destination. The
destination table now lists an application or room and a Subscriber,
and both pages say "resource address".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Keep the spam-label and STIR/SHAKEN pointers, which are prerequisites
for getting answered rather than diagnostics, in the calling-number
section, and drop the link definitions left with no home.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every Resource type is dialed the same way, so the table lists Resource
once and names the common types it reaches, conference rooms included.
Say plainly that queues and media streams are not Resources and only
SWML connect reaches them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The dial response's queued status is not a status_events value, so a
reader waiting on a "queued" webhook waits forever. Name the status the
response reports, say that created is the first subscribable event, and
add the status-to-event table.

Flags one gap with NEEDS SOURCE: nothing in the repo says which event,
if any, accompanies failed, canceled, or completed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Verified against prime-rails at 02473273. The status webhook fires only
when the call state string is itself listed in status_events, so the
event name and the status are the same value and there is no mapping.
Replaces the NEEDS SOURCE with the answer: busy, no-answer, failed, and
canceled deliver no callback at all, so a call that never connects is
silent. Adds busy and no-answer, which the table was missing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Devon-White and others added 6 commits September 8, 2026 17:23
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Which parameter carries the destination in each client belongs in the
reference, not in a starter guide. Keeps the one fact a beginner can
trip over: the Relay client dials phone and SIP only, not resource
addresses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each example now says what it does rather than what a fictional taxi
company does with it, so a reader matches an example to their own task
without carrying the story.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three ordered steps — calling address, credential, project limits —
each answering "for what I'm dialing, what do I need" in a table
instead of prose a reader has to filter. Drops the last of the
per-client field plumbing.

Calling-address rules verified against the Calling API's own
destination validation: E.164 for PSTN, E.164 or SIP URI or a short
token for SIP, unchecked for a resource address.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An address is one of the ways a destination is identified, so calling
the from side an "address" made the two read as one thing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Devon-White and others added 13 commits September 8, 2026 17:50
The step is a decision about what you're dialing; the caller ID rule is
what follows from it. Also fixes the phone-number row, which read as if
you needed to own a number in order to dial one — the requirement is on
the caller ID the call presents.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Splits the single Resource row into the things people recognize — a
registered SIP phone, a Subscriber, an application, a conference room —
with the platform term alongside and a real address in each row, so the
Resource concept lands from the table instead of ahead of it.

Keys the caller ID table on the address form dialed, which is what the
API actually branches on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The section named the Calling API, Relay WebSockets, Server SDK clients,
the Browser SDK, SIP credentials, and a Call Flow Builder node before a
reader knows what any of them are. There are two ways a call starts, so
say that; the interfaces arrive later where they matter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sentence-long labels overlapped — two rows both opened "A SIP phone" —
so the column no longer told you which row was which. One short noun
per row, with the concepts explained underneath instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two real errors. The table was keyed on the destination with a column
of caller ID rules, so the phone row read as "you can only dial numbers
you own" — the destination is unrestricted; the from is what's held to
numbers your project owns. And the resource row's "any value is
accepted" read as though any address were dialable, when a resource
address has to resolve to a Resource in your Space.

Now states outright that any PSTN number, any SIP endpoint, and any
existing resource address are dialable, with trial projects called out
as the one narrowing case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reciting caller ID rules against destination rows left the reader
working out what to actually go get. The column is now "What you need",
so each row is a checklist for dialing that destination — including the
Resource having to exist at that address, and optional SIP auth.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dialing a Resource needs a credential allowed to reach it, which the
guide never said. A project API token covers every Resource in its own
project; a SAT reaches what its Subscriber reaches; a guest token only
the allowed_addresses set at creation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A SAT authenticates a subscriber client, so the row is "Your web or
mobile app". Also refreshes the page description, which still named a
section removed earlier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three steps: what the destination needs, which credential, place the
call. The trial and international limits move into step one, where the
other destination constraints already live.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Neither is a step you take, so both move into a titled Warning ahead of
the steps, where a trial user hits it before working through them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drops the "Forward an inbound call" example and its three code tabs,
and narrows "How outbound calls start" to the request path. Fixes the
counts and the intro line that promised bridging two callers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant