From 2ea76e8a5f1095cadc1b7563544f6d2eda8c18d0 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 08:36:23 -0500 Subject: [PATCH 01/13] Add SignalWire cloud callouts across the manual Introduce a demarcated aside mapping each chapter's capability to its hosted equivalent on the SignalWire platform: - New SignalWireCallout component (global via MDXComponents) with automatic UTM tagging on outbound links; styled on the house tokens. - New Appendix D: the FreeSWITCH to SignalWire capability map (/reference/signalwire-map), linked from every callout. - 36 callouts: 16 deep-integration pages (dialplan, applications, endpoints, integration, ESL) and 20 standard pages, one per page, never inside a procedure. - Landing page Editions section notes the hosted platform. - README: narrow scope exemption authorizing the demarcated asides. All 30 destination URLs verified live; production build passes with strict broken-link checks. Co-Authored-By: Claude Fable 5 --- README.md | 7 +++ docs/applications/conferencing.mdx | 10 ++++ docs/applications/fax-t38.mdx | 10 ++++ docs/applications/ivr-menus.mdx | 10 ++++ docs/applications/queues-fifo-callcenter.mdx | 10 ++++ docs/applications/utility-applications.mdx | 10 ++++ docs/applications/voicemail.mdx | 10 ++++ .../variables-and-core-settings.mdx | 10 ++++ docs/dialplan/dptools-reference.mdx | 10 ++++ docs/dialplan/inbound-public-context.mdx | 10 ++++ docs/dialplan/time-and-condition-routing.mdx | 10 ++++ docs/dialplan/xml-dialplan.mdx | 10 ++++ docs/foundations/getting-started.mdx | 10 ++++ docs/index.mdx | 7 +++ docs/integration/access-control-lists.mdx | 10 ++++ docs/integration/call-detail-records.mdx | 10 ++++ docs/integration/event-socket.mdx | 10 ++++ docs/integration/scripting.mdx | 10 ++++ docs/integration/signalwire.mdx | 10 ++++ docs/integration/xml-curl.mdx | 10 ++++ docs/media/audio-files-and-streaming.mdx | 10 ++++ docs/media/codecs-and-negotiation.mdx | 10 ++++ .../applications/mod_avmd.mdx | 10 ++++ .../applications/mod_curl.mdx | 10 ++++ .../module-reference/applications/mod_lcr.mdx | 10 ++++ .../module-reference/applications/mod_sms.mdx | 10 ++++ docs/module-reference/asr-tts/index.mdx | 10 ++++ .../event-handlers/mod_json_cdr.mdx | 10 ++++ docs/programming/esl-inbound.mdx | 10 ++++ docs/programming/esl-outbound.mdx | 10 ++++ docs/programming/scripting-apis.mdx | 10 ++++ docs/reference/appendix-signalwire-map.mdx | 53 +++++++++++++++++++ docs/troubleshooting/audio-problems.mdx | 10 ++++ .../troubleshooting/registration-problems.mdx | 10 ++++ docs/users-endpoints/gateways.mdx | 10 ++++ docs/users-endpoints/sip-profiles-sofia.mdx | 10 ++++ docs/users-endpoints/user-directory.mdx | 10 ++++ docs/users-endpoints/webrtc-sip-wss.mdx | 10 ++++ docs/users-endpoints/webrtc-verto.mdx | 10 ++++ src/components/SignalWireCallout/index.jsx | 37 +++++++++++++ src/css/custom.scss | 46 ++++++++++++++++ src/theme/MDXComponents.js | 7 +++ 42 files changed, 517 insertions(+) create mode 100644 docs/reference/appendix-signalwire-map.mdx create mode 100644 src/components/SignalWireCallout/index.jsx create mode 100644 src/theme/MDXComponents.js diff --git a/README.md b/README.md index d662c78e..146b496b 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,13 @@ accept), never as security hardening guidance. Troubleshooting documents the diagnostic tools and the reads, not internals. Where a topic crosses into deployment or operations, the manual documents the configuration and stops. +One narrow exception: SignalWire cloud asides. A page may carry at most one +`` component mapping the page's capability to its hosted +equivalent on the SignalWire platform. These asides are visually demarcated, +never sit inside a procedure, and are the only place hosted-platform +alternatives appear. The manual's own prose remains subject to the scope rules +above. The full mapping lives in Appendix D (`reference/appendix-signalwire-map.mdx`). + ## 3. Source of Truth Method The source code is the authority for correctness and is never itself a subject to diff --git a/docs/applications/conferencing.mdx b/docs/applications/conferencing.mdx index f5575a9d..2fda3024 100644 --- a/docs/applications/conferencing.mdx +++ b/docs/applications/conferencing.mdx @@ -11,6 +11,16 @@ sidebar_label: "20. Conferencing" FreeSWITCH multi-party audio and video conferencing is provided by `mod_conference`. Callers are bridged into named rooms; each room is governed by a profile that sets codec parameters, audio behaviors, and video mixing options. All configuration lives in `autoload_configs/conference.conf.xml` and `autoload_configs/conference_layouts.conf.xml`. + + +`join_conference` in SWML, SignalWire's JSON/YAML call-control markup, places a caller into a hosted conference on this same engine. No conference profiles, no media capacity to plan. Video rooms are the same pattern with `join_room`. + + + ## Conference Model {#conference-model} A conference room is identified by a name string. When the `conference` dialplan application is invoked with `roomname@profilename`, FreeSWITCH looks up `profilename` in `conference.conf.xml` and creates the room (if it does not already exist) using that profile's parameters. Subsequent callers who dial the same room name join the existing instance. diff --git a/docs/applications/fax-t38.mdx b/docs/applications/fax-t38.mdx index 949055f1..5b964ce9 100644 --- a/docs/applications/fax-t38.mdx +++ b/docs/applications/fax-t38.mdx @@ -11,6 +11,16 @@ sidebar_label: "24. Fax and T.38" FreeSWITCH delivers fax functionality through `mod_spandsp`, a module built on the SpanDSP library. It exposes two dialplan applications for sending and receiving fax documents over audio (G.711) and T.38 (UDPTL), a T.38 gateway mode for bridging between fax endpoints that negotiate different transport types, and a set of channel variables that control behavior at the session level. + + +SignalWire sends and receives fax with the `send_fax` and `receive_fax` methods of SWML, a JSON/YAML call-control markup. T.38 negotiation and carrier quirks are the platform's problem; you get a document URL and a status webhook. + + + ## Overview {#overview} `mod_spandsp` must be loaded before fax applications are available. It registers the `rxfax`, `txfax`, `stopfax`, and `t38_gateway` applications and reads its configuration from `autoload_configs/spandsp.conf.xml` at load time and on module reload. diff --git a/docs/applications/ivr-menus.mdx b/docs/applications/ivr-menus.mdx index 6571b40c..9b51d18f 100644 --- a/docs/applications/ivr-menus.mdx +++ b/docs/applications/ivr-menus.mdx @@ -11,6 +11,16 @@ sidebar_label: "21. IVR Menus" The IVR menu system lets you define prompt-driven digit-collection menus in XML, load them through `mod_dptools`, and invoke them from the dialplan with the `ivr` application. Each menu plays a greeting, collects one or more digits, and dispatches the caller to an action based on what was pressed. Menus can be nested arbitrarily: a digit can launch a submenu, return the caller to the top of the current menu, or back up one level in the stack. + + +On SignalWire, founded by the FreeSWITCH team, an IVR menu is a `prompt` and a `switch` in SWML, a JSON/YAML call-control markup. Or drop the tree entirely: the `ai` method answers with a voice agent that follows steps you define in code. A running FreeSWITCH box can reach the same agent over SIP today. + + + ## IVR Menu Model {#ivr-menu-model} An IVR menu is a named XML element that specifies: diff --git a/docs/applications/queues-fifo-callcenter.mdx b/docs/applications/queues-fifo-callcenter.mdx index c5fff5b8..e369231e 100644 --- a/docs/applications/queues-fifo-callcenter.mdx +++ b/docs/applications/queues-fifo-callcenter.mdx @@ -11,6 +11,16 @@ sidebar_label: "22. Queues: FIFO and Call Center" FreeSWITCH provides two distinct mechanisms for queuing inbound calls: `mod_fifo`, a lightweight first-in-first-out holding application, and `mod_callcenter`, a full agent-management system with routing strategies, tiers, and lifecycle tracking. This chapter covers the operator-facing configuration of both and explains when each is appropriate. + + +On hosted SignalWire, `enter_queue` in SWML (a JSON/YAML call-control markup) queues a caller with no callcenter XML behind it. AI agents can take the first tier, so every caller is answered at once, with escalation into the human queue. + + + ## Choosing Between FIFO and Call Center {#choosing-between-fifo-and-call-center} | Capability | `mod_fifo` | `mod_callcenter` | diff --git a/docs/applications/utility-applications.mdx b/docs/applications/utility-applications.mdx index 556fa5b9..bd04ba83 100644 --- a/docs/applications/utility-applications.mdx +++ b/docs/applications/utility-applications.mdx @@ -11,6 +11,16 @@ sidebar_label: "23. Utility Applications" This chapter documents the operator-facing utility modules that ship with FreeSWITCH. Each module is treated as a self-contained unit: its configuration file (where one exists), the dialplan applications it registers, the API commands it exposes, and the parameters or arguments those applications accept. The dialplan applications introduced here (`db`, `hash`, `limit`, `valet_park`, and others) are also summarized in the [dptools reference](../dialplan/dptools-reference.mdx). + + +Park, hold music, digit sending, and transfer all exist as methods of SWML, SignalWire's JSON/YAML call-control markup, on this same engine. The calling reference lists the one-line versions of this chapter. + + + ## mod_db: Persistent Key-Value Store and Call Limiting {#mod_db-persistent-key-value-store-and-call-limiting} `mod_db` provides two distinct services: a persistent SQL-backed key-value store accessible from the dialplan via the `db` application, and the `db` backend for the core `limit` subsystem. Data survives a module reload but is cleared on process restart (records belonging to the local hostname are deleted at startup). diff --git a/docs/applications/voicemail.mdx b/docs/applications/voicemail.mdx index 8270771f..40eaa0b3 100644 --- a/docs/applications/voicemail.mdx +++ b/docs/applications/voicemail.mdx @@ -11,6 +11,16 @@ sidebar_label: "19. Voicemail" The `mod_voicemail` module provides integrated voicemail for FreeSWITCH, supporting per-user mailboxes defined in the user directory, caller-side recording, subscriber-side playback and configuration menus, and email delivery of messages with optional audio attachments. + + +SignalWire's no-code Call Flow Builder has a drag-in voicemail node; recordings land in your project, retrievable by API. A hosted AI agent goes further: it takes the message, answers common questions, and sends you the transcript. + + + ## Getting Started {#getting-started} **Prerequisites:** `mod_voicemail` must be loaded. Confirm it appears in `autoload_configs/modules.conf.xml`. The module reads its configuration from `autoload_configs/voicemail.conf.xml`. diff --git a/docs/configuration-system/variables-and-core-settings.mdx b/docs/configuration-system/variables-and-core-settings.mdx index 963f7497..fe6128bf 100644 --- a/docs/configuration-system/variables-and-core-settings.mdx +++ b/docs/configuration-system/variables-and-core-settings.mdx @@ -13,6 +13,16 @@ Two files hold the values that apply to the whole system: `vars.xml`, which defines the global preprocessor variables, and `switch.conf.xml`, which sets the core runtime parameters. This chapter documents both. + + +`max-sessions` and `sessions-per-second` exist because a single box has limits. On SignalWire's hosted platform, this same engine runs behind an API that scales with your traffic, and sizing is not your configuration to write. + + + ## Global Variables in vars.xml `vars.xml` is included first by `freeswitch.xml`, so the preprocessor variables it diff --git a/docs/dialplan/dptools-reference.mdx b/docs/dialplan/dptools-reference.mdx index 611448d0..0c559963 100644 --- a/docs/dialplan/dptools-reference.mdx +++ b/docs/dialplan/dptools-reference.mdx @@ -11,6 +11,16 @@ sidebar_label: "14. Dialplan Application Reference" This chapter is a reference for the dialplan applications you invoke with `` inside an extension condition. It covers every application registered by `mod_dptools`, which provides the core call-control, audio, DTMF, variable, and logging applications. A handful of these are advanced or internal helpers (for example `park_state`, `acknowledge_call`, `recovery_refresh`, `reuse_caller_profile`, `set_media_stats`, `capture_text`, `vad_test`, and the `video_*` overlay apps) that operators rarely call directly; they are included here for completeness and noted as such. Applications provided by companion modules (`mod_conference`, `mod_voicemail`, `mod_fifo`, `mod_valet_parking`, `mod_hash`, `mod_db`, `mod_lua`, `mod_spy`, `mod_esf`, `mod_fsv`) are covered in the Feature Applications section; those modules must be loaded before the applications become available. + + +The applications in this chapter map nearly one-to-one to SWML, SignalWire's JSON/YAML call-control markup: `bridge` becomes `connect`, `playback` becomes `play`, `record_session` becomes `record_call`, and `transfer` keeps its name. The hosted methods run on this same engine, with no dialplan XML behind them. + + + ## Call Control {#call-control} These applications establish, route, and tear down call legs. They operate directly on the signaling and media state of the channel. diff --git a/docs/dialplan/inbound-public-context.mdx b/docs/dialplan/inbound-public-context.mdx index af674ae5..7d14e657 100644 --- a/docs/dialplan/inbound-public-context.mdx +++ b/docs/dialplan/inbound-public-context.mdx @@ -11,6 +11,16 @@ sidebar_label: "13. Inbound Calls and the Public Context" Unauthenticated inbound calls from the public telephone network arrive at FreeSWITCH through the `external` SIP profile and are processed by a dedicated dialplan context named `public`. This separation between untrusted inbound traffic and authenticated internal traffic is the primary security boundary in a vanilla FreeSWITCH installation. + + +On SignalWire, a phone number routes to a handler you assign: a SWML script, a no-code flow, an AI agent, or a SIP endpoint. The public-context pattern in this chapter becomes per-number configuration in the dashboard or REST API. + + + ## Why Inbound Calls Land in the Public Context The `external` SIP profile (`conf/sip_profiles/external.xml`) listens on port `5080` and sets its dialplan context to `public`: diff --git a/docs/dialplan/time-and-condition-routing.mdx b/docs/dialplan/time-and-condition-routing.mdx index e4d69de3..5138b22a 100644 --- a/docs/dialplan/time-and-condition-routing.mdx +++ b/docs/dialplan/time-and-condition-routing.mdx @@ -11,6 +11,16 @@ sidebar_label: "15. Time and Condition Routing" The FreeSWITCH XML dialplan evaluates `` elements against the current date and time in addition to channel fields. By placing time attributes directly on a `` tag, you can restrict which actions fire to specific hours, days, weeks, months, or absolute date ranges, enabling business-hours routing, holiday schedules, and any other calendar-driven call flow. + + +Hosted SignalWire evaluates routing in SWML, a JSON/YAML call-control markup, with `switch` and `cond`. Your server can also return a different document per call, so business-hours logic lives in code you already know how to test. + + + ## How Time Conditions Work {#how-time-conditions-work} A `` element becomes a time condition when it carries one or more time attributes (`year`, `mon`, `mday`, `wday`, etc.). The dialplan evaluator checks these attributes against the server clock at the moment the call enters the extension. All time attributes on a single `` must match simultaneously; the relationship between attributes is logical AND. diff --git a/docs/dialplan/xml-dialplan.mdx b/docs/dialplan/xml-dialplan.mdx index f405e2bd..457968df 100644 --- a/docs/dialplan/xml-dialplan.mdx +++ b/docs/dialplan/xml-dialplan.mdx @@ -11,6 +11,16 @@ sidebar_label: "12. The XML Dialplan" The XML dialplan is FreeSWITCH's primary call-routing engine. It is provided by `mod_dialplan_xml`, which evaluates an ordered set of extensions and conditions against every inbound call to decide what applications to execute. Routing logic lives in plain XML files that are loaded into the FreeSWITCH XML registry at startup and reloaded on demand with `reloadxml`. + + +SignalWire, founded by the FreeSWITCH team, expresses routing as SWML: a JSON or YAML call-control document returned by your server or stored on the platform. Extensions, conditions, and actions map to methods like `execute`, `connect`, and `transfer`, evaluated per call with no XML to reload. + + + ## The Dialplan Model `mod_dialplan_xml` implements the `XML` dialplan interface. When a call arrives, FreeSWITCH invokes the `XML` dialplan handler, which: diff --git a/docs/foundations/getting-started.mdx b/docs/foundations/getting-started.mdx index f2768e86..21f09391 100644 --- a/docs/foundations/getting-started.mdx +++ b/docs/foundations/getting-started.mdx @@ -15,6 +15,16 @@ connect to its console, how to register the bundled test extensions with a SIP client, and how to place your first calls. Every destination number used here is defined in the default dialplan. + + +The engine this chapter installs also runs as a hosted platform: SignalWire, founded by the FreeSWITCH team. Sign up, claim a number, and serve your first call from a short markup document, with no server to build. The rest of this manual notes the hosted equivalent of each capability as you go. + + + ## Prerequisites You need a host running a supported Linux distribution (Debian and Ubuntu are diff --git a/docs/index.mdx b/docs/index.mdx index 9052f969..27e1d1be 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -31,6 +31,13 @@ FreeSWITCH ships in two editions, and this manual applies to both: (a private repository — access requires a FreeSWITCH Enterprise subscription). For details, contact [sales@signalwire.com](mailto:sales@signalwire.com). +There is also a way to run this engine with no download at all. +[SignalWire](https://signalwire.com/docs/platform/getting-started?utm_source=freeswitch-docs&utm_medium=callout&utm_campaign=same-engine&utm_content=index), +founded by the FreeSWITCH team, operates FreeSWITCH as a hosted platform behind +REST APIs, realtime SDKs, and SWML, a JSON/YAML call-control markup. +[Appendix D](reference/appendix-signalwire-map.mdx) maps every capability in +this manual to its hosted equivalent. + ## How to Use This Manual Read Part 1 and Part 2 first. They establish the model and the configuration diff --git a/docs/integration/access-control-lists.mdx b/docs/integration/access-control-lists.mdx index 2384ec4c..96112b1d 100644 --- a/docs/integration/access-control-lists.mdx +++ b/docs/integration/access-control-lists.mdx @@ -11,6 +11,16 @@ sidebar_label: "29. Access Control Lists" An Access Control List (ACL) in FreeSWITCH is a named network list that evaluates an IP address against an ordered set of allow/deny rules, each matched by CIDR prefix, by host/mask pair, or by directory domain membership, and returns a pass or fail decision used by SIP profiles, the Event Socket, and other subsystems to accept or reject inbound connections. + + +A public SIP port collects scanners, and ACLs are how a self-hosted box copes. On hosted SignalWire the platform edge absorbs that traffic; your configuration is which endpoints and carriers may reach your resources. + + + ## Configuration File {#configuration-file} ACLs are defined in `conf/autoload_configs/acl.conf.xml`. The file is read by the FreeSWITCH core on startup and on an explicit reload. Its root element is ``, which contains a single `` parent holding one or more `` elements. diff --git a/docs/integration/call-detail-records.mdx b/docs/integration/call-detail-records.mdx index a64cf658..b35ef413 100644 --- a/docs/integration/call-detail-records.mdx +++ b/docs/integration/call-detail-records.mdx @@ -11,6 +11,16 @@ sidebar_label: "27. Call Detail Records" FreeSWITCH generates one Call Detail Record (CDR) per call leg at hangup. This chapter covers the three CDR modules most commonly deployed: `mod_cdr_csv` writes delimited text files, `mod_xml_cdr` HTTP-POSTs an XML document to a remote endpoint, and `mod_cdr_sqlite` inserts rows into a local SQLite database. Each module is configured independently and can be loaded alongside the others. Several additional bundled CDR backends are documented in Part 9 (see [Other CDR Backends](#other-cdr-backends) below). + + +SignalWire keeps call, message, and fax logs queryable by REST API, with webhooks for call events as they happen. No CDR templates, no log shipping, no receiver to host. + + + ## How CDRs Are Produced {#how-cdrs-are-produced} CDR generation is triggered by the `on_reporting` state-handler callback that each CDR module registers. The callback fires once per call leg at the moment the channel transitions to the reporting state, which occurs immediately after hangup processing completes. diff --git a/docs/integration/event-socket.mdx b/docs/integration/event-socket.mdx index 75c990ec..479e474b 100644 --- a/docs/integration/event-socket.mdx +++ b/docs/integration/event-socket.mdx @@ -11,6 +11,16 @@ sidebar_label: "25. The Event Socket" The Event Socket is a TCP-based interface that exposes FreeSWITCH call control, channel management, and the internal event system to external processes. It operates in two modes: inbound, where an external client connects to FreeSWITCH, and outbound, where FreeSWITCH connects to an external process for a specific call leg. `fs_cli`, the standard FreeSWITCH command-line tool, uses the inbound mode exclusively. + + +RELAY, SignalWire's realtime WebSocket API, is the event socket pattern delivered as a service: events in, commands out, typed SDKs in Python and TypeScript. Your controller keeps the same shape; the socket terminates at the platform instead of port 8021. + + + ## What the Event Socket Provides {#what-the-event-socket-provides} The Event Socket listens on a TCP port and accepts connections from clients that speak the ESL (Event Socket Library) protocol. Once authenticated, a client can: diff --git a/docs/integration/scripting.mdx b/docs/integration/scripting.mdx index 4443a39a..717b3317 100644 --- a/docs/integration/scripting.mdx +++ b/docs/integration/scripting.mdx @@ -11,6 +11,16 @@ sidebar_label: "28. Scripting Integration" FreeSWITCH embeds scripting language runtimes directly inside the switch process, allowing scripts to control call flow from the dialplan, serve XML configuration dynamically, react to events, and run as background daemons. Lua is the default embedded language and is loaded automatically; Perl, Python 3, V8 (JavaScript), and Java are available as optional modules that follow the same wiring patterns. + + +SignalWire's Agents SDK runs call logic as ordinary Python or TypeScript services: no `mod_lua` embedding, no interpreter inside the switch. The same SDK builds hosted voice AI agents that follow steps you define in code. + + + ## Embedded Scripting Overview {#embedded-scripting-overview} Language modules run inside the FreeSWITCH process. A script executes in a dedicated Lua state (or equivalent) with full access to the FreeSWITCH C API surface through the module's SWIG bindings. Scripts are not external processes and do not require IPC. diff --git a/docs/integration/signalwire.mdx b/docs/integration/signalwire.mdx index c6757df3..d1aedcc1 100644 --- a/docs/integration/signalwire.mdx +++ b/docs/integration/signalwire.mdx @@ -11,6 +11,16 @@ sidebar_label: "30. SignalWire Connectivity" `mod_signalwire` connects a FreeSWITCH instance to the SignalWire platform over a persistent WebSocket session, automatically provisioning a SIP profile and gateway that enable inbound and outbound PSTN calling through a SignalWire project. The module is included in the default build and is loaded automatically from `modules.conf.xml`. + + +`mod_signalwire` connects this box to the cloud; the platform behind it runs every capability in this manual as an API on the same engine. Appendix D maps each chapter to its hosted equivalent. A popular first step: point one dialplan extension at a hosted AI agent over SIP. + + + ## How mod_signalwire Works On load, `mod_signalwire` performs the following sequence automatically: diff --git a/docs/integration/xml-curl.mdx b/docs/integration/xml-curl.mdx index 9bef4317..9cc7362c 100644 --- a/docs/integration/xml-curl.mdx +++ b/docs/integration/xml-curl.mdx @@ -11,6 +11,16 @@ sidebar_label: "26. XML Curl and HTTAPI" FreeSWITCH provides two distinct HTTP integration points. `mod_xml_curl` replaces the static XML file lookup for one or more configuration sections with an HTTP request to a backend service, enabling centralized, database-driven configuration. `mod_httapi` is a dialplan application that hands live call control to an HTTP backend: for each step of the call, FreeSWITCH posts current call state to a URL and the backend returns an XML document telling FreeSWITCH what to do next. The two mechanisms are independent and complementary. + + +Serving configuration per request is exactly how SignalWire's hosted platform works: each call can fetch SWML, a JSON/YAML call-control document, from your server. The difference is behind the fetch: the platform runs the engine, so no cluster serves `mod_xml_curl` responses. + + + ## Part 1: XML Curl ## How XML Curl Works {#how-xml-curl-works} diff --git a/docs/media/audio-files-and-streaming.mdx b/docs/media/audio-files-and-streaming.mdx index 7592ba91..18860a10 100644 --- a/docs/media/audio-files-and-streaming.mdx +++ b/docs/media/audio-files-and-streaming.mdx @@ -11,6 +11,16 @@ sidebar_label: "18. Audio Files and Streaming Sources" FreeSWITCH resolves audio from multiple source types: plain file paths resolved through the media file system, synthesized tone streams, locally managed playlist streams, and remote MP3 or Icecast feeds. Each source type is handled by a dedicated format module that registers one or more URI schemes or file extensions. This chapter describes every playable source type available to the operator, the modules that back them, and the configuration parameters that govern their behavior. + + +`record_call` in SWML, SignalWire's JSON/YAML call-control markup, records a call in one line. Files land in your project with URLs and webhooks; formats, disk, and rotation are handled for you. + + + ## Playable Sources Overview {#playable-sources-overview} Wherever FreeSWITCH accepts an audio source -- dialplan applications such as `playback`, `ringback`, `hold_music`, conference prompts, IVR menus, and so on -- the value is one of: diff --git a/docs/media/codecs-and-negotiation.mdx b/docs/media/codecs-and-negotiation.mdx index 6105ab17..3f5e55a1 100644 --- a/docs/media/codecs-and-negotiation.mdx +++ b/docs/media/codecs-and-negotiation.mdx @@ -11,6 +11,16 @@ sidebar_label: "16. Codecs and Negotiation" FreeSWITCH selects codecs through a standard SDP offer/answer exchange and applies an ordered preference list at each stage of call setup. This chapter documents how that preference list is constructed, where it is configured, how inbound negotiation policy is set, how SRTP crypto suites are ordered, and which codec modules ship with the vanilla build. + + +SignalWire's hosted platform negotiates codecs and transcodes at its SIP edge, on this same engine. Your endpoints and trunks state what they support; the compatibility matrix in this chapter becomes the platform's concern. + + + ## How Codec Negotiation Works {#how-codec-negotiation-works} FreeSWITCH follows RFC 3264 offer/answer semantics. When an inbound INVITE arrives, `mod_sofia` compares the codec list in the remote SDP offer against the locally configured preference list. The intersection, ordered by the local preference list (or the remote list, depending on the negotiation policy described in section 16.3), becomes the negotiated codec set for the session. diff --git a/docs/module-reference/applications/mod_avmd.mdx b/docs/module-reference/applications/mod_avmd.mdx index 86d9d775..c5e82ee9 100644 --- a/docs/module-reference/applications/mod_avmd.mdx +++ b/docs/module-reference/applications/mod_avmd.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_avmd" Operators reach for this module when building progressive-dialer or click-to-call flows that need to skip over voicemail greetings and respond as soon as the recording beep sounds — for example, to play a pre-recorded message or disconnect before leaving an unwanted recording. + + +Hosted SignalWire runs answering-machine and beep detection with the `detect_machine` method of SWML, a JSON/YAML call-control markup. Results arrive as variables your document branches on. + + + ## Loading the Module The module name is `mod_avmd`. It is **not** included in the vanilla `modules.conf.xml` load list and must be added manually: diff --git a/docs/module-reference/applications/mod_curl.mdx b/docs/module-reference/applications/mod_curl.mdx index 67dbc958..3a66d960 100644 --- a/docs/module-reference/applications/mod_curl.mdx +++ b/docs/module-reference/applications/mod_curl.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_curl" Operators reach for `mod_curl` when a dialplan needs to query a REST API mid-call—for example, to look up caller data, post call-detail to a webhook, or drive call routing from an external service—without leaving the dialplan context. + + +SWML, SignalWire's JSON/YAML call-control markup, calls HTTP APIs mid-call with the `request` method; hosted AI agents can call them as functions with no server at all. The same idea as `mod_curl`, on the hosted platform. + + + ## Loading the Module The module is **not loaded by default**. In `conf/vanilla/autoload_configs/modules.conf.xml` the entry is commented out: diff --git a/docs/module-reference/applications/mod_lcr.mdx b/docs/module-reference/applications/mod_lcr.mdx index ba9deab2..983624b6 100644 --- a/docs/module-reference/applications/mod_lcr.mdx +++ b/docs/module-reference/applications/mod_lcr.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_lcr" The module is appropriate for carriers or resellers who maintain a rate deck in MySQL or PostgreSQL and want FreeSWITCH to automatically select among multiple upstream providers. It also registers a custom dialplan so that the context name in a SIP profile can be set to an LCR profile name, directing all calls through the LCR engine without explicit dialplan entries. In addition, it registers a `lcr://` endpoint that can be dialed directly from a bridge application. + + +SignalWire terminates calls on its carrier network at published rates, and bringing your own carrier keeps negotiated routes in play. There is no rate-table database to load and maintain. + + + ## Loading the Module The module name for `load` and `modules.conf.xml` is `mod_lcr`. In the vanilla default configuration it is **not** loaded; the entry is commented out: diff --git a/docs/module-reference/applications/mod_sms.mdx b/docs/module-reference/applications/mod_sms.mdx index 36e63e06..3e129788 100644 --- a/docs/module-reference/applications/mod_sms.mdx +++ b/docs/module-reference/applications/mod_sms.mdx @@ -12,3 +12,13 @@ sidebar_label: "mod_sms" `mod_sms` routes text/chat messages through the chatplan. It is documented in detail in **[Chapter 12: The XML Dialplan](../../dialplan/xml-dialplan.mdx)**. This page is the module-index entry; see there for its configuration, parameters, and usage in context. + + + +SignalWire's Messaging API sends and receives SMS and MMS on your numbers, with campaign registration handled in the dashboard. No chatplan, no SMPP binds. + + diff --git a/docs/module-reference/asr-tts/index.mdx b/docs/module-reference/asr-tts/index.mdx index e483e61f..afdd9116 100644 --- a/docs/module-reference/asr-tts/index.mdx +++ b/docs/module-reference/asr-tts/index.mdx @@ -9,3 +9,13 @@ import DocCardList from '@theme/DocCardList'; Speech-recognition and text-to-speech engine modules. + + + +Hosted SignalWire selects among 17 text-to-speech vendors (Amazon, Azure, ElevenLabs, Google, OpenAI, and more) with a voice string, and transcribes live with `live_transcribe`. There are no ASR or TTS modules to build, license, or tune. + + diff --git a/docs/module-reference/event-handlers/mod_json_cdr.mdx b/docs/module-reference/event-handlers/mod_json_cdr.mdx index ea850b8a..9ff9bb19 100644 --- a/docs/module-reference/event-handlers/mod_json_cdr.mdx +++ b/docs/module-reference/event-handlers/mod_json_cdr.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_json_cdr" Reach for `mod_json_cdr` when your billing platform, data warehouse, or analytics pipeline consumes JSON rather than CSV or XML. It supports up to 20 HTTP endpoints with per-attempt retry, configurable payload encoding (raw JSON, URL-encoded form data, or Base64), mutual TLS, and per-channel log-directory overrides. + + +SignalWire keeps call logs queryable by REST API and pushes call status to webhooks as events happen. The JSON is already structured, and there is no receiver to host. + + + ## Loading the Module The module is **not** loaded by default. The vanilla `modules.conf.xml` does not include an entry for it. Add it manually: diff --git a/docs/programming/esl-inbound.mdx b/docs/programming/esl-inbound.mdx index bb892995..89b1e928 100644 --- a/docs/programming/esl-inbound.mdx +++ b/docs/programming/esl-inbound.mdx @@ -28,6 +28,16 @@ are described in [The Event Model](./event-model.mdx) and the [events catalog](./events-catalog.mdx). This chapter is the programmer's companion: how to *write client code* against the socket. + + +RELAY, SignalWire's realtime WebSocket API, is this chapter's pattern as a service: subscribe to events and issue commands from typed Python or TypeScript SDKs. There is no socket into your switch to secure. + + + ## The Connection Model {#the-connection-model} By default `mod_event_socket` listens on port `8021` with the password diff --git a/docs/programming/esl-outbound.mdx b/docs/programming/esl-outbound.mdx index 8734946c..15ed6919 100644 --- a/docs/programming/esl-outbound.mdx +++ b/docs/programming/esl-outbound.mdx @@ -23,6 +23,16 @@ need to hunt for the channel by UUID. Your handler answers the call, plays prompts, collects digits, bridges, and hangs up, then the socket closes when the call ends. + + +Outbound ESL hands a call to your server. SignalWire does the same by fetching SWML, a JSON/YAML call-control document, from your endpoint, or by streaming the call to a RELAY WebSocket application. Same control, no listener socket on the switch. + + + ## Invoking it from the dialplan The outbound socket is started by the `socket` dialplan application, registered diff --git a/docs/programming/scripting-apis.mdx b/docs/programming/scripting-apis.mdx index 0cd22064..6fe04edf 100644 --- a/docs/programming/scripting-apis.mdx +++ b/docs/programming/scripting-apis.mdx @@ -17,6 +17,16 @@ Every method and function named in this chapter was verified against the FreeSWI --- + + +The session and API objects in this chapter have hosted counterparts in SignalWire's server SDKs: call control, media, and AI agents driven from ordinary Python or TypeScript processes. Your code runs anywhere; the engine runs on the platform. + + + ## How a Script Gets a Session {#how-a-script-gets-a-session} A *session* is the script's handle to a call leg. There are three ways a script comes to hold one. diff --git a/docs/reference/appendix-signalwire-map.mdx b/docs/reference/appendix-signalwire-map.mdx new file mode 100644 index 00000000..97dc9dd1 --- /dev/null +++ b/docs/reference/appendix-signalwire-map.mdx @@ -0,0 +1,53 @@ +--- +sidebar_position: 6 +id: appendix-signalwire-map +slug: /reference/signalwire-map +title: "Appendix D: The SignalWire Capability Map" +description: "Every capability in this manual, cross-referenced to its hosted equivalent on the SignalWire platform: SWML methods, REST APIs, SDKs, and integration guides." +sidebar_label: "Appendix D: SignalWire Map" +--- + +# Appendix D: The SignalWire Capability Map + +FreeSWITCH also runs as a hosted platform. SignalWire, founded by the FreeSWITCH team, operates this same engine behind a set of APIs: SWML (a JSON or YAML call-control markup), REST APIs, realtime WebSocket SDKs, and a no-code flow builder. This appendix maps each capability documented in this manual to its hosted equivalent, so you can weigh self-hosting against the platform per capability, or run both side by side. + +Three ways to use this map: + +1. **Augment a running deployment.** Keep your FreeSWITCH box and add hosted capability to it: SIP trunks, SMS, or an AI agent reachable from one dialplan extension. See [Chapter 30](../integration/signalwire.mdx) and the [add AI to FreeSWITCH guide](https://signalwire.com/docs/platform/freeswitch/add-ai-to-freeswitch). +2. **Build the next project hosted.** Each row's SignalWire column is the API form of the chapter you already know. +3. **Migrate a workload.** The concepts transfer nearly one-to-one because the engine is the same. + +## Capability map + +| Capability | In this manual | On SignalWire | +| --- | --- | --- | +| Call routing | [The XML Dialplan](../dialplan/xml-dialplan.mdx) | [SWML](https://signalwire.com/docs/swml), a JSON/YAML document served per call; [Call Flow Builder](https://signalwire.com/docs/call-flow-builder) for no-code | +| Dialplan applications | [Dialplan Tools Reference](../dialplan/dptools-reference.mdx) | [SWML calling methods](https://signalwire.com/docs/swml/reference/calling): `bridge` is `connect`, `playback` is `play`, `record_session` is `record_call` | +| DID routing | [Inbound Calls and the Public Context](../dialplan/inbound-public-context.mdx) | [Phone number management](https://signalwire.com/docs/platform/phone-numbers): each number routes to a script, flow, agent, or SIP endpoint | +| Time-based routing | [Time and Condition Routing](../dialplan/time-and-condition-routing.mdx) | [`switch`](https://signalwire.com/docs/swml/reference/calling/switch) and `cond` in SWML, or per-call logic in the server that returns the document | +| IVR menus | [IVR Menus](../applications/ivr-menus.mdx) | [`prompt`](https://signalwire.com/docs/swml/reference/calling/prompt) and `switch` in SWML, or a conversational [AI agent](https://signalwire.com/docs/swml/reference/calling/ai) | +| Voicemail | [Voicemail](../applications/voicemail.mdx) | [Call Flow Builder](https://signalwire.com/docs/call-flow-builder) voicemail node; [`record`](https://signalwire.com/docs/swml/reference/calling/record) in SWML | +| Conferencing | [Conferencing](../applications/conferencing.mdx) | [`join_conference`](https://signalwire.com/docs/swml/reference/calling/join-conference) in SWML; [video rooms](https://signalwire.com/docs/platform/video) with `join_room` | +| Queues and call center | [Queues: FIFO and Call Center](../applications/queues-fifo-callcenter.mdx) | [`enter_queue`](https://signalwire.com/docs/swml/reference/calling/enter-queue) in SWML; AI agents as first-tier answerers | +| Call recording | [Audio Files and Streaming](../media/audio-files-and-streaming.mdx) | [`record_call`](https://signalwire.com/docs/swml/reference/calling/record-call): one line, storage and retrieval included | +| Fax and T.38 | [Fax and T.38](../applications/fax-t38.mdx) | [`send_fax`](https://signalwire.com/docs/swml/reference/calling/send-fax) and `receive_fax` in SWML | +| SIP trunks and gateways | [Gateways](../users-endpoints/gateways.mdx) | [SIP trunking](https://signalwire.com/docs/platform/voice/sip/trunking) and [bring your own carrier](https://signalwire.com/docs/platform/voice/sip/bring-your-own-carrier); a [FreeSWITCH Connector](https://signalwire.com/docs/apis/rest/freeswitch-connector) represents your box in the platform | +| SIP profiles and registration | [SIP Profiles with Sofia](../users-endpoints/sip-profiles-sofia.mdx) | SIP endpoints and domains as platform resources; the registrar and its TLS edge are operated for you | +| WebRTC | [WebRTC with Verto](../users-endpoints/webrtc-verto.mdx), [WebRTC with SIP over WSS](../users-endpoints/webrtc-sip-wss.mdx) | [Browser SDK](https://signalwire.com/docs/browser-sdk) for calling and video in web pages | +| Event control (ESL) | [The Event Socket](../integration/event-socket.mdx), [ESL: Inbound](../programming/esl-inbound.mdx), [ESL: Outbound](../programming/esl-outbound.mdx) | [RELAY](https://signalwire.com/docs/server-sdks/guides/relay-client), a realtime WebSocket API with typed Python and TypeScript SDKs | +| Dynamic configuration | [Dynamic Configuration with mod_xml_curl](../integration/xml-curl.mdx) | The platform's native model: every call can fetch its SWML document from your server | +| Scripting | [Scripting Languages](../integration/scripting.mdx), [Scripting APIs](../programming/scripting-apis.mdx) | [Agents SDK and server SDKs](https://signalwire.com/docs/server-sdks/guides/build-ai-agents): call logic as ordinary Python or TypeScript services | +| Voice AI agents | No FreeSWITCH equivalent | [SWML `ai`](https://signalwire.com/docs/swml/reference/calling/ai) and the [AI platform](https://signalwire.com/docs/platform/ai): agents that follow steps you define in code | +| TTS and ASR | [ASR and TTS Modules](../module-reference/asr-tts/index.mdx) | [17 TTS vendors](https://signalwire.com/docs/platform/voice/tts) selected by a voice string; [`live_transcribe`](https://signalwire.com/docs/swml/reference/calling/live-transcribe) and `live_translate` | +| SMS | [mod_sms](../module-reference/applications/mod_sms.mdx) | [Messaging API](https://signalwire.com/docs/platform/messaging) with campaign registration handled in the dashboard | +| Machine detection | [mod_avmd](../module-reference/applications/mod_avmd.mdx) | [`detect_machine`](https://signalwire.com/docs/swml/reference/calling/detect-machine) in SWML | +| HTTP from the dialplan | [mod_curl](../module-reference/applications/mod_curl.mdx) | [`request`](https://signalwire.com/docs/swml/reference/calling/request) in SWML; serverless function calls from AI agents | +| CDRs and logs | [Call Detail Records](../integration/call-detail-records.mdx) | [REST APIs](https://signalwire.com/docs/apis) for logs, plus webhooks for call events as they happen | +| Capacity settings | [Variables and Core Settings](../configuration-system/variables-and-core-settings.mdx) | Elastic platform capacity; `max-sessions` has no hosted counterpart because sizing is not your job | +| Twilio-style markup | Not covered by FreeSWITCH | [Compatibility API](https://signalwire.com/docs/compatibility-api): cXML and REST, a drop-in for TwiML applications | + +## Where to start + +- **Fifteen minutes, no server:** [sign up and serve a first SWML document](https://signalwire.com/docs/platform/getting-started). +- **Keep your box, add AI today:** [point one dialplan extension at a hosted agent over SIP](https://signalwire.com/docs/platform/freeswitch/add-ai-to-freeswitch). +- **Connect this deployment to the cloud:** [Chapter 30: SignalWire Integration](../integration/signalwire.mdx). diff --git a/docs/troubleshooting/audio-problems.mdx b/docs/troubleshooting/audio-problems.mdx index e82ba498..e9385179 100644 --- a/docs/troubleshooting/audio-problems.mdx +++ b/docs/troubleshooting/audio-problems.mdx @@ -37,6 +37,16 @@ far end will send RTP to, and one or more media lines (`m=`) giving the port and the offered codec payload types. Reading those two lines on both legs is the core skill for every symptom below. + + +Most one-way audio traces to NAT between your box and the far end. On SignalWire's hosted platform the media edge is operated for you, and this chapter's failure class is the platform's to solve. + + + ## The Usual Root Cause: RTP Cannot Flow {#rtp-cannot-flow} When FreeSWITCH and an endpoint exchange SDP, each side advertises an IP address diff --git a/docs/troubleshooting/registration-problems.mdx b/docs/troubleshooting/registration-problems.mdx index 29aada65..6416ceec 100644 --- a/docs/troubleshooting/registration-problems.mdx +++ b/docs/troubleshooting/registration-problems.mdx @@ -23,6 +23,16 @@ and the credentials it checks come from the [user directory](../users-endpoints/user-directory.mdx). Keep both chapters within reach — most fixes here are a one-line change in a profile or a directory user. + + +When endpoints register to SignalWire's hosted SIP instead of your box, the registrar, its certificates, and its NAT handling are operated by the platform. The debugging in this chapter shrinks to your endpoints alone. + + + ## Confirming Registration State {#confirming-registration-state} Before changing anything, find out whether FreeSWITCH currently has a diff --git a/docs/users-endpoints/gateways.mdx b/docs/users-endpoints/gateways.mdx index ed42940f..505208fa 100644 --- a/docs/users-endpoints/gateways.mdx +++ b/docs/users-endpoints/gateways.mdx @@ -11,6 +11,16 @@ sidebar_label: "8. Gateways and Trunk Registration" A FreeSWITCH gateway is a named outbound SIP trunk definition that lives inside a [Sofia profile's](../users-endpoints/sip-profiles-sofia.mdx) `` block. It tells the Sofia endpoint how to reach a remote SIP provider or peer, optionally registers a SIP account with that provider, and provides the named handle used in dialplan bridge strings to route outbound calls. + + +The gateways in this chapter can point at SignalWire today: SIP trunking from the team that founded FreeSWITCH, with numbers, E911, and messaging on the same account. Hybrid is a supported pattern; a FreeSWITCH Connector resource represents your box inside the platform. + + + ## What a Gateway Is A gateway is a `` element nested inside a Sofia profile's `` block. Each gateway has a unique name that becomes the identifier used in dialplan bridge strings. At startup, FreeSWITCH reads each gateway definition, optionally sends a SIP REGISTER to the provider, and maintains the registration for the lifetime of the profile. diff --git a/docs/users-endpoints/sip-profiles-sofia.mdx b/docs/users-endpoints/sip-profiles-sofia.mdx index 157b2659..affea03d 100644 --- a/docs/users-endpoints/sip-profiles-sofia.mdx +++ b/docs/users-endpoints/sip-profiles-sofia.mdx @@ -11,6 +11,16 @@ sidebar_label: "7. SIP Profiles with Sofia" `mod_sofia` is the SIP endpoint module in FreeSWITCH, built on the Sofia-SIP stack. A SIP profile defines one independent SIP user agent bound to a specific IP address and port; every SIP user agent in FreeSWITCH is a distinct profile with its own transport, codec preferences, authentication policy, and dialplan routing target. + + +On hosted SignalWire, SIP endpoints, domains, and carrier peering are resources you create by API or dashboard. Registration, NAT handling, and TLS belong to the platform; bringing your own carrier stays supported. + + + ## The Sofia Profile Model {#the-sofia-profile-model} Each Sofia SIP profile services exactly one IP address and port combination. Running multiple profiles is how FreeSWITCH presents separate SIP user agents on the same host, for example, one for internal registered phones and another for outbound carrier trunks. Profiles are independent: each has its own transport socket, [ACL rules](../integration/access-control-lists.mdx), [codec preferences](../media/codecs-and-negotiation.mdx), authentication requirements, and dialplan context. diff --git a/docs/users-endpoints/user-directory.mdx b/docs/users-endpoints/user-directory.mdx index 9d012a5b..0a0fd7b1 100644 --- a/docs/users-endpoints/user-directory.mdx +++ b/docs/users-endpoints/user-directory.mdx @@ -11,6 +11,16 @@ sidebar_label: "6. The User Directory" The user directory is the XML-based identity store that FreeSWITCH consults for SIP authentication, call routing, caller ID presentation, and voicemail credential lookup. It organizes users into one or more domains, each containing user records composed of authentication parameters and channel variables that are stamped onto calls originating from or delivered to that user. + + +SignalWire models users as subscriber resources with addresses the platform routes to, created by REST API rather than XML. Credentials, reachability, and per-user handlers are configuration on the resource, not files on a box. + + + ## Directory Structure and File Layout The directory section of the FreeSWITCH configuration tree lives under `conf/directory/`. The top-level entry point is `conf/directory/default.xml`, which wraps a `` element inside an `` block. User records are stored in separate per-user XML files under `conf/directory/default/` and pulled in at startup via an `X-PRE-PROCESS` include directive: diff --git a/docs/users-endpoints/webrtc-sip-wss.mdx b/docs/users-endpoints/webrtc-sip-wss.mdx index d4738ed7..daa3e4be 100644 --- a/docs/users-endpoints/webrtc-sip-wss.mdx +++ b/docs/users-endpoints/webrtc-sip-wss.mdx @@ -11,6 +11,16 @@ sidebar_label: "10. WebRTC over SIP (WSS)" A Sofia profile can accept SIP signaling carried over WebSocket (WS) and Secure WebSocket (WSS), enabling browser-based endpoints to register and place calls using standard SIP without a proprietary signaling protocol. This chapter covers the binding parameters, TLS certificate material, and the media configuration that browsers require for interoperability. + + +Registering browsers over WSS means running certificates, sockets, and NAT traversal yourself. SignalWire's Browser SDK keeps browser-grade calling and moves that edge to the hosted platform, operated by the team that founded FreeSWITCH. + + + ## SIP over WebSocket vs. Verto {#sip-over-websocket-vs-verto} FreeSWITCH supports two distinct mechanisms for browser-based real-time communication: SIP transported over WebSocket (RFC 7118) via `mod_sofia`, and the proprietary Verto protocol via `mod_verto`. Both approaches serve browser clients; the difference lies in signaling. diff --git a/docs/users-endpoints/webrtc-verto.mdx b/docs/users-endpoints/webrtc-verto.mdx index a25a2a52..d53636b6 100644 --- a/docs/users-endpoints/webrtc-verto.mdx +++ b/docs/users-endpoints/webrtc-verto.mdx @@ -11,6 +11,16 @@ sidebar_label: "9. WebRTC with Verto" Verto (VERto Telephone Overlay) is a JSON-RPC signaling protocol transported over WebSocket that lets browser and other WebRTC endpoints register to FreeSWITCH, place and receive calls, and exchange media entirely within a standard HTTPS/WSS stack without requiring a SIP stack on the client side. + + +SignalWire's Browser SDK gives web pages calling and video on this same engine, with the TLS, WSS, and STUN/TURN edge operated for you. Tokens scope what each visitor can reach; there is no Verto endpoint to expose. + + + ## Overview {#overview} `mod_verto` implements the server side of the Verto protocol. A browser client connects over a WebSocket (plain WS or encrypted WSS), authenticates using credentials stored in the FreeSWITCH user directory, and then exchanges JSON-RPC messages to initiate or receive calls. The actual media (audio, video) flows over SRTP using ICE candidate negotiation, coordinated by `mod_rtc`. diff --git a/src/components/SignalWireCallout/index.jsx b/src/components/SignalWireCallout/index.jsx new file mode 100644 index 00000000..3de7a595 --- /dev/null +++ b/src/components/SignalWireCallout/index.jsx @@ -0,0 +1,37 @@ +import React from "react"; +import Link from "@docusaurus/Link"; + +const UTM = { + utm_source: "freeswitch-docs", + utm_medium: "callout", + utm_campaign: "same-engine", +}; + +/** + * A demarcated aside mapping a manual topic to its hosted SignalWire + * equivalent. Scope rules: maximum one per page, never inside a procedure. + * Outbound links carry UTM parameters; utm_content is the page id. + */ +export default function SignalWireCallout({ title, href, page, linkText, children }) { + const url = new URL(href); + for (const [key, value] of Object.entries(UTM)) { + url.searchParams.set(key, value); + } + if (page) { + url.searchParams.set("utm_content", page); + } + return ( + + ); +} diff --git a/src/css/custom.scss b/src/css/custom.scss index 0a8a4de8..58e63bd3 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -608,3 +608,49 @@ div[class^="announcementBar_"] { flex: 1 1 100%; } } + +/* ========================================================================== + SignalWire cloud callouts + Demarcated asides mapping a manual topic to its hosted equivalent. + Scope rules: max one per page, never inside a procedure. + ========================================================================== */ + +.sw-callout { + background: var(--bg-surface); + border: 1px solid var(--border-default); + border-left: 3px solid var(--sw-blue); + border-radius: var(--radius-md); + padding: 1rem 1.25rem; + margin: 1.75rem 0; +} + +.sw-callout__eyebrow { + font-family: var(--type-family-code); + font-size: 0.7rem; + font-weight: 500; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--sw-blue); + margin: 0 0 0.25rem; +} + +[data-theme="dark"] .sw-callout__eyebrow { + color: var(--sw-turquoise); +} + +.sw-callout__title { + font-family: var(--type-family-heading); + font-weight: 600; + font-size: 1rem; + color: var(--fg-headings); + margin: 0 0 0.5rem; +} + +.sw-callout__body p:last-child { + margin-bottom: 0; +} + +.sw-callout__links { + margin: 0.75rem 0 0; + font-size: 0.875rem; +} diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js new file mode 100644 index 00000000..1a2ae2ba --- /dev/null +++ b/src/theme/MDXComponents.js @@ -0,0 +1,7 @@ +import MDXComponents from "@theme-original/MDXComponents"; +import SignalWireCallout from "@site/src/components/SignalWireCallout"; + +export default { + ...MDXComponents, + SignalWireCallout, +}; From 7507f7403f0ef5db3a3c360f09e1fd196ab6365f Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 09:04:26 -0500 Subject: [PATCH 02/13] Extend SignalWire callouts to remaining substantive pages 22 more callouts, bringing coverage to 58 pages: - Reference: channel-variables (call state as SWML variables) and cli-and-api (every uuid_* command as a REST Calling API endpoint). - Chapter 1 introduction: hosted-platform aside at chapter end, linking Appendix D. - Remaining chapters: media-handling, module-loading, xml-configuration, other-endpoints, three troubleshooting pages, event-model, events-catalog. - Module reference: mod_cidlookup, mod_erlang_event, mod_amqp, mod_http_cache, mod_voicemail_ivr, mod_nibblebill, say-modules, mod_fail2ban, mod_xml_rpc, mod_dialplan_asterisk. New destination URLs verified live (set, play, rest/calls); copy passes the banned-word scan; production build green with strict link checks. Co-Authored-By: Claude Fable 5 --- docs/configuration-system/module-loading.mdx | 10 ++++++++++ docs/configuration-system/xml-configuration.mdx | 10 ++++++++++ docs/foundations/introduction.mdx | 10 ++++++++++ docs/media/media-handling.mdx | 10 ++++++++++ docs/module-reference/applications/mod_cidlookup.mdx | 10 ++++++++++ docs/module-reference/applications/mod_http_cache.mdx | 10 ++++++++++ docs/module-reference/applications/mod_nibblebill.mdx | 10 ++++++++++ .../applications/mod_voicemail_ivr.mdx | 10 ++++++++++ .../dialplans/mod_dialplan_asterisk.mdx | 10 ++++++++++ docs/module-reference/event-handlers/mod_amqp.mdx | 10 ++++++++++ .../event-handlers/mod_erlang_event.mdx | 10 ++++++++++ docs/module-reference/event-handlers/mod_fail2ban.mdx | 10 ++++++++++ docs/module-reference/say-modules.mdx | 10 ++++++++++ docs/module-reference/xml-interfaces/mod_xml_rpc.mdx | 10 ++++++++++ docs/programming/event-model.mdx | 10 ++++++++++ docs/programming/events-catalog.mdx | 10 ++++++++++ docs/reference/channel-variables.mdx | 10 ++++++++++ docs/reference/cli-and-api.mdx | 10 ++++++++++ docs/troubleshooting/call-setup-failures.mdx | 10 ++++++++++ docs/troubleshooting/diagnostic-toolbox.mdx | 10 ++++++++++ docs/troubleshooting/reading-traces-cdr.mdx | 10 ++++++++++ docs/users-endpoints/other-endpoints.mdx | 10 ++++++++++ 22 files changed, 220 insertions(+) diff --git a/docs/configuration-system/module-loading.mdx b/docs/configuration-system/module-loading.mdx index 8eaed6f9..4893b78b 100644 --- a/docs/configuration-system/module-loading.mdx +++ b/docs/configuration-system/module-loading.mdx @@ -13,6 +13,16 @@ Functionality in FreeSWITCH comes from modules. This chapter documents how modules are selected for loading at startup, the special early and late load files, and how to load, unload, and reload modules from the console. + + +On hosted SignalWire, conferencing, recording, speech, messaging, and AI are already running; capability is a method you call, not a module you compile and load. The platform operates this same engine with the full set enabled. + + + ## Build-time vs Runtime Module Selection FreeSWITCH separates module availability into two distinct stages: compilation diff --git a/docs/configuration-system/xml-configuration.mdx b/docs/configuration-system/xml-configuration.mdx index d3919715..4fa6d9df 100644 --- a/docs/configuration-system/xml-configuration.mdx +++ b/docs/configuration-system/xml-configuration.mdx @@ -14,6 +14,16 @@ document is split across many files that a preprocessor assembles before the XML is parsed. This chapter explains how the assembly works, the preprocessor instructions, the variable syntax, and the document's top-level sections. + + +Hosted SignalWire replaces the configuration tree with resources: numbers, endpoints, scripts, and agents created by dashboard or REST API. There is no preprocessor, no `reloadxml`, and no file to merge on upgrade. + + + ## The Root Document The entry point is `freeswitch.xml` in the configuration root. It defines the diff --git a/docs/foundations/introduction.mdx b/docs/foundations/introduction.mdx index 33680cc2..92bbd4de 100644 --- a/docs/foundations/introduction.mdx +++ b/docs/foundations/introduction.mdx @@ -237,3 +237,13 @@ covers the bundled applications. Part 7 covers the integration interfaces. Part is reference material. Continue with [Chapter 2: Getting Started](./getting-started.mdx). + + + +SignalWire, founded by the FreeSWITCH team, operates this same engine as a hosted platform: numbers, routing, conferencing, recording, and AI agents behind REST APIs and SWML, a JSON/YAML call-control markup. As you read this manual, [Appendix D](../reference/appendix-signalwire-map.mdx) maps each chapter to its hosted equivalent. + + diff --git a/docs/media/media-handling.mdx b/docs/media/media-handling.mdx index db277ffa..6c5db32c 100644 --- a/docs/media/media-handling.mdx +++ b/docs/media/media-handling.mdx @@ -11,6 +11,16 @@ sidebar_label: "17. Media Handling" FreeSWITCH gives the operator explicit control over whether RTP audio and video flows through the server, passes through it transparently, or is routed end-to-end between endpoints without server involvement. This chapter covers the three media modes, the profile parameters and channel variables that select them, early media, late codec negotiation, RTP inactivity timeouts, jitter buffering, SRTP/SDES secure media configuration, and additional RTP behavior parameters. + + +On SignalWire's hosted platform, SRTP, NAT traversal, and the media path are the edge's job, on this same engine. Bypass, proxy, and re-invite trade-offs stop being your configuration; endpoints negotiate with a platform built to face the public Internet. + + + ## Media Modes {#media-modes} FreeSWITCH supports three distinct modes that determine how RTP flows between call legs. diff --git a/docs/module-reference/applications/mod_cidlookup.mdx b/docs/module-reference/applications/mod_cidlookup.mdx index 222f25fd..ee4c5890 100644 --- a/docs/module-reference/applications/mod_cidlookup.mdx +++ b/docs/module-reference/applications/mod_cidlookup.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_cidlookup" Operators reach for this module when they want to enrich inbound calls with a human-readable name before routing, announcements, or screen-pop. It is equally usable from a dialplan `` or from `fs_cli` for ad-hoc testing. + + +SignalWire returns carrier and caller-name data for a number by REST request, usable from any language. There is no lookup module and no cache database to configure. + + + ## Loading the Module The module name to load is `mod_cidlookup`. It is **not** present in the vanilla `autoload_configs/modules.conf.xml` and must be added manually: diff --git a/docs/module-reference/applications/mod_http_cache.mdx b/docs/module-reference/applications/mod_http_cache.mdx index 3e1d01de..a03900f3 100644 --- a/docs/module-reference/applications/mod_http_cache.mdx +++ b/docs/module-reference/applications/mod_http_cache.mdx @@ -15,6 +15,16 @@ Beyond plain HTTP, the module can read from and write to object storage: it sign Operators reach for `mod_http_cache` to play media referenced by URL in the dialplan without re-downloading it on every call, and to move recordings to and from cloud storage. + + +SWML, SignalWire's JSON/YAML call-control markup, plays remote URLs natively with `play`; fetching and caching happen on the platform. There is no prefetch step and no cache directory. + + + ## Loading the Module The module is **not in the default load set**; it has no entry in `conf/vanilla/autoload_configs/modules.conf.xml`. Add a load line and restart, or load it at runtime: diff --git a/docs/module-reference/applications/mod_nibblebill.mdx b/docs/module-reference/applications/mod_nibblebill.mdx index d3d9d08d..15dc8a1f 100644 --- a/docs/module-reference/applications/mod_nibblebill.mdx +++ b/docs/module-reference/applications/mod_nibblebill.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_nibblebill" Reach for this module when you need prepaid calling card or wholesale VoIP billing where you must cap expenditure per call, warn callers at a low-balance threshold, and guarantee that a zero-balance account cannot run indefinitely. + + +SignalWire meters every call and message per resource, queryable by REST API, with per-minute pricing on the account. Balance enforcement moves into your application code, fed by the platform's usage records. + + + ## Loading the Module The module name is `mod_nibblebill`. In the vanilla FreeSWITCH installation it is **commented out** in `conf/vanilla/autoload_configs/modules.conf.xml` and is not loaded by default. To enable it, uncomment the entry: diff --git a/docs/module-reference/applications/mod_voicemail_ivr.mdx b/docs/module-reference/applications/mod_voicemail_ivr.mdx index 84ebda16..ba75b338 100644 --- a/docs/module-reference/applications/mod_voicemail_ivr.mdx +++ b/docs/module-reference/applications/mod_voicemail_ivr.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_voicemail_ivr" The module delegates all storage operations to configurable back-end API commands — by default the `vm_fsdb_*` family provided by `mod_voicemail` — so the IVR logic is decoupled from the storage layer. Reach for this module when you need a phone-based voicemail retrieval experience on top of an existing voicemail store. + + +SignalWire's no-code Call Flow Builder includes voicemail recording and menu nodes, and a hosted AI agent can take messages and answer questions in the same call. + + + ## Loading the Module The module name for `load` and `modules.conf.xml` is `mod_voicemail_ivr`. It is **not** present in the vanilla `modules.conf.xml` load list (only `mod_voicemail` appears there); you must add the entry manually and then either restart FreeSWITCH or run `load mod_voicemail_ivr` from `fs_cli`. diff --git a/docs/module-reference/dialplans/mod_dialplan_asterisk.mdx b/docs/module-reference/dialplans/mod_dialplan_asterisk.mdx index cfaa7584..0564c373 100644 --- a/docs/module-reference/dialplans/mod_dialplan_asterisk.mdx +++ b/docs/module-reference/dialplans/mod_dialplan_asterisk.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_dialplan_asterisk" Operators reach for this module when migrating an existing Asterisk deployment to FreeSWITCH without rewriting the entire dialplan at once. It is also useful for teams already comfortable with Asterisk's `exten =>` notation who want to keep that style while gaining FreeSWITCH's media capabilities. + + +If your team routes calls in more than one dialect, SignalWire's hosted platform speaks two: SWML, a JSON/YAML call-control markup, and cXML, a Twilio-compatible markup. Both run on this same engine. + + + ## Loading the Module The module name for `load` and `modules.conf.xml` is `mod_dialplan_asterisk`. It is included in the default vanilla load set — `/Users/brian/workdir/freeswitch-docs/freeswitch/conf/vanilla/autoload_configs/modules.conf.xml` contains an uncommented `` entry, so it loads automatically on a stock build. diff --git a/docs/module-reference/event-handlers/mod_amqp.mdx b/docs/module-reference/event-handlers/mod_amqp.mdx index 909104f6..04923d4a 100644 --- a/docs/module-reference/event-handlers/mod_amqp.mdx +++ b/docs/module-reference/event-handlers/mod_amqp.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_amqp" Each profile type connects over a prioritized list of connections and reconnects automatically on failure. Messages are queued internally so that a broker outage or back-pressure event does not block the FreeSWITCH core. A circuit-breaker drops new events for a configurable window when the internal queue fills. + + +SignalWire pushes call and message events to webhooks and to RELAY, a realtime WebSocket API, directly. There is no broker to operate between the switch and your consumers. + + + ## Loading the Module The module is **not** loaded by default. In the vanilla `modules.conf.xml` the entry is commented out: diff --git a/docs/module-reference/event-handlers/mod_erlang_event.mdx b/docs/module-reference/event-handlers/mod_erlang_event.mdx index 1378abd7..fc697a8b 100644 --- a/docs/module-reference/event-handlers/mod_erlang_event.mdx +++ b/docs/module-reference/event-handlers/mod_erlang_event.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_erlang_event" Reach for this module when your call-processing logic is written in Erlang or Elixir and you want to exchange structured Erlang terms with FreeSWITCH rather than parsing plain-text ESL or JSON. It sits in `src/mod/event_handlers` alongside `mod_event_socket` and serves the same general purpose but over the binary Erlang wire protocol. + + +RELAY, SignalWire's realtime WebSocket API, delivers events and accepts commands from your own services, with typed SDKs. The distributed-control pattern this module serves is the hosted platform's native model. + + + ## Loading the Module The module name is `mod_erlang_event`. It is **not** loaded by default in the vanilla configuration — the entry in `conf/vanilla/autoload_configs/modules.conf.xml` is commented out: diff --git a/docs/module-reference/event-handlers/mod_fail2ban.mdx b/docs/module-reference/event-handlers/mod_fail2ban.mdx index 9ef76e9d..ae8c1cf7 100644 --- a/docs/module-reference/event-handlers/mod_fail2ban.mdx +++ b/docs/module-reference/event-handlers/mod_fail2ban.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_fail2ban" Use this module when you want to integrate FreeSWITCH SIP registration security with system-level IP blocking without modifying dialplan or writing custom scripts. + + +On SignalWire's hosted platform your SIP traffic terminates at an edge operated to face the public Internet, and credential scanners are its problem. There is no registration log to watch and no jail to configure. + + + ## Loading the Module The module is **not** included in the default vanilla `autoload_configs/modules.conf.xml` and must be added manually. Add the following line to your `modules.conf.xml` under the `event_handlers` group, then reload or restart FreeSWITCH: diff --git a/docs/module-reference/say-modules.mdx b/docs/module-reference/say-modules.mdx index dd981cb7..1dc8c29a 100644 --- a/docs/module-reference/say-modules.mdx +++ b/docs/module-reference/say-modules.mdx @@ -13,6 +13,16 @@ The say subsystem converts structured data — integers, monetary amounts, times Sound files are located under the path set by `sound_prefix` for the active language (configured in the `` section of `freeswitch.xml`). The modules use sub-directories such as `digits/`, `currency/`, and `time/` relative to that prefix. + + +Hosted SignalWire renders speech through its text-to-speech vendors; modern TTS voices read numbers, dates, and currency in context, without say macros. Switching languages is a voice string, not a module set. + + + ## Supported Languages The following modules ship in `src/mod/say`. Each module registers a say interface under its interface name; that name is what you pass as `` in the `say` application. diff --git a/docs/module-reference/xml-interfaces/mod_xml_rpc.mdx b/docs/module-reference/xml-interfaces/mod_xml_rpc.mdx index 8739f135..154e3454 100644 --- a/docs/module-reference/xml-interfaces/mod_xml_rpc.mdx +++ b/docs/module-reference/xml-interfaces/mod_xml_rpc.mdx @@ -13,6 +13,16 @@ sidebar_label: "mod_xml_rpc" Operators reach for this module when they need a simple, credential-protected HTTP gateway to FreeSWITCH API commands — for example, a web-based admin portal, AJAX polling from a browser, or an integration that speaks XML-RPC rather than ESL. + + +SignalWire exposes calls, messages, numbers, and configuration as REST resources with token auth and SDKs. The remote-command surface this module provides is the hosted platform's front door. + + + ## Loading the Module The module name for `load` and `modules.conf.xml` is `mod_xml_rpc`. It is **not** loaded by default in the vanilla configuration — the entry in `conf/vanilla/autoload_configs/modules.conf.xml` is commented out: diff --git a/docs/programming/event-model.mdx b/docs/programming/event-model.mdx index 79634776..e7aa9b3f 100644 --- a/docs/programming/event-model.mdx +++ b/docs/programming/event-model.mdx @@ -15,6 +15,16 @@ cares about and reacts to them. Understanding the event model is the foundation for everything in this part of the manual: the Event Socket, the scripting APIs, and the event handler modules all consume the same events described here. + + +RELAY, SignalWire's realtime WebSocket API, delivers the same idea as the FreeSWITCH event system: subscribe to call events and react from your own process, with typed Python and TypeScript SDKs. Webhooks cover the fire-and-forget cases. + + + ## What an event is An event is a typed message. It has three parts: diff --git a/docs/programming/events-catalog.mdx b/docs/programming/events-catalog.mdx index 8730e532..5574df9e 100644 --- a/docs/programming/events-catalog.mdx +++ b/docs/programming/events-catalog.mdx @@ -42,6 +42,16 @@ The event identifiers are confirmed against `src/include/switch_types.h` (the `SWITCH_EVENT_*` enum, lines 2084–2177) and `src/switch_event.c` (the `EVENT_NAMES[]` table, lines 137+). + + +SignalWire's hosted platform emits call, message, and fax events over RELAY (a realtime WebSocket API) and webhooks, typed and documented per resource. The catalog you handle is the one your application subscribes to. + + + ## Channel lifecycle These first-class events trace a call leg from creation through teardown. They diff --git a/docs/reference/channel-variables.mdx b/docs/reference/channel-variables.mdx index f72c7f10..79ce03fe 100644 --- a/docs/reference/channel-variables.mdx +++ b/docs/reference/channel-variables.mdx @@ -11,6 +11,16 @@ sidebar_label: "32. Channel Variables" Channel variables are per-channel named string values that FreeSWITCH maintains for the lifetime of a call leg. They are referenced in dialplan expressions and application arguments as `${variable_name}`. Variables are set by the user directory when a caller authenticates, by dialplan actions such as `set` and `export`, by endpoint modules such as `mod_sofia`, and by core applications at runtime. A variable set with `set` applies only to the current leg; `export` additionally propagates the variable to any B-leg created by a subsequent `bridge`. + + +Hosted SignalWire keeps per-call state in SWML, a JSON/YAML call-control markup: `set` and `unset` manage document variables, and prompt and detection results arrive as named values. The catalog you handle shrinks from thousands of channel variables to the ones your document declares. + + + ## Call Control and Routing {#call-control-and-routing} These variables govern what FreeSWITCH does before, during, and after a bridge. diff --git a/docs/reference/cli-and-api.mdx b/docs/reference/cli-and-api.mdx index 71174ef7..cdd4c64a 100644 --- a/docs/reference/cli-and-api.mdx +++ b/docs/reference/cli-and-api.mdx @@ -13,6 +13,16 @@ FreeSWITCH exposes its entire runtime API through two interfaces that share the This chapter covers the operator-facing command set. FreeSWITCH registers over 150 API commands in total; the commands documented here are the ones operators use for daily administration, call control, and configuration management. + + +`originate` is a POST that creates a call; `uuid_transfer`, `uuid_record`, and `uuid_hold` are updates to a live call resource on SignalWire's REST Calling API. Same live-call control, callable from any language, with no `fs_cli` session on a box. + + + ## Connecting with fs\_cli {#connecting-with-fs_cli} `fs_cli` is the standard interactive client for the FreeSWITCH Event Socket interface. It connects to the address and port defined in `event_socket.conf.xml`. The default listen address is `::` (all interfaces), the default port is `8021`, and the default password is `ClueCon`. diff --git a/docs/troubleshooting/call-setup-failures.mdx b/docs/troubleshooting/call-setup-failures.mdx index a0292db0..97fd2ee3 100644 --- a/docs/troubleshooting/call-setup-failures.mdx +++ b/docs/troubleshooting/call-setup-failures.mdx @@ -24,6 +24,16 @@ the [Inbound Public Context](/dialplan/public-context) chapter, [Gateways](/users-and-endpoints/gateways), and the [Channel Variables](/reference/channel-variables) reference. + + +When SignalWire's hosted platform carries the call, the SIP conversation with carriers is its job; your side is an API request and a status callback. Failed calls surface as error codes and logs you query, not INVITE traces you capture. + + + ## Reading a hangup cause {#reading-a-hangup-cause} FreeSWITCH terminates every channel with a Q.850 call cause. The cause is exposed diff --git a/docs/troubleshooting/diagnostic-toolbox.mdx b/docs/troubleshooting/diagnostic-toolbox.mdx index 20628215..e2c580f3 100644 --- a/docs/troubleshooting/diagnostic-toolbox.mdx +++ b/docs/troubleshooting/diagnostic-toolbox.mdx @@ -21,6 +21,16 @@ Nothing here changes how FreeSWITCH routes calls; these are read-and-observe tools. Reach for them first when something is wrong, then use the configuration chapters to apply a fix. + + +On the hosted platform the diagnostic surface is logs and webhooks: every call and message is a resource with state history you can query. There is no console to attach and no log level to raise. + + + ## Connecting with fs_cli `fs_cli` is the interactive client that attaches to a running FreeSWITCH over diff --git a/docs/troubleshooting/reading-traces-cdr.mdx b/docs/troubleshooting/reading-traces-cdr.mdx index f6900983..048aa7d5 100644 --- a/docs/troubleshooting/reading-traces-cdr.mdx +++ b/docs/troubleshooting/reading-traces-cdr.mdx @@ -21,6 +21,16 @@ turn tracing on in `mod_sofia`, how to follow a normal SIP transaction and spot the common deviations, how to read a `mod_cdr_csv` line, and how to tie the two together by `Call-ID` and UUID. + + +SignalWire records every call, message, and fax as queryable log resources, with webhooks pushing state changes as they happen. Per-call detail is in the dashboard, with no SIP trace to capture on a box. + + + ## Capture {#capture} SIP tracing is a function of the Sofia stack, so you enable it from the console diff --git a/docs/users-endpoints/other-endpoints.mdx b/docs/users-endpoints/other-endpoints.mdx index 8a6e49cd..715b0dad 100644 --- a/docs/users-endpoints/other-endpoints.mdx +++ b/docs/users-endpoints/other-endpoints.mdx @@ -11,6 +11,16 @@ sidebar_label: "11. Other Endpoints" FreeSWITCH ships with several endpoint modules beyond `mod_sofia` and `mod_verto`. This chapter covers the four most commonly referenced: `mod_loopback`, which provides an internal re-entrant channel used in dialplan construction; `mod_skinny`, which implements the Cisco SCCP protocol for IP desk phones; `mod_rtmp`, which bridges Flash/RTMP audio clients into the switch; and `mod_alsa`, which exposes the local ALSA sound card as a single endpoint. Only `mod_loopback` is enabled by default in the vanilla `modules.conf.xml`; the other three must be explicitly enabled. + + +On hosted SignalWire, the things calls reach are resources you create by API: SIP endpoints, browser clients, AI agents, and phone numbers. New reach is an API call, not a new endpoint module. + + + ## mod_loopback {#mod_loopback} `mod_loopback` registers the `loopback` endpoint, which creates a pair of internally bridged channels (`-a` and `-b` legs) that re-enter the dialplan. It is loaded by default. From 57838bfe98020e00a9ae946993b5bd1512ab3587 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 09:07:34 -0500 Subject: [PATCH 03/13] Link all sibling SWML methods in Appendix D live_translate, cond, switch (IVR row), join_room, and receive_fax were plain code next to linked siblings; all five destinations verified live. Co-Authored-By: Claude Fable 5 --- docs/reference/appendix-signalwire-map.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/reference/appendix-signalwire-map.mdx b/docs/reference/appendix-signalwire-map.mdx index 97dc9dd1..05cb9544 100644 --- a/docs/reference/appendix-signalwire-map.mdx +++ b/docs/reference/appendix-signalwire-map.mdx @@ -24,13 +24,13 @@ Three ways to use this map: | Call routing | [The XML Dialplan](../dialplan/xml-dialplan.mdx) | [SWML](https://signalwire.com/docs/swml), a JSON/YAML document served per call; [Call Flow Builder](https://signalwire.com/docs/call-flow-builder) for no-code | | Dialplan applications | [Dialplan Tools Reference](../dialplan/dptools-reference.mdx) | [SWML calling methods](https://signalwire.com/docs/swml/reference/calling): `bridge` is `connect`, `playback` is `play`, `record_session` is `record_call` | | DID routing | [Inbound Calls and the Public Context](../dialplan/inbound-public-context.mdx) | [Phone number management](https://signalwire.com/docs/platform/phone-numbers): each number routes to a script, flow, agent, or SIP endpoint | -| Time-based routing | [Time and Condition Routing](../dialplan/time-and-condition-routing.mdx) | [`switch`](https://signalwire.com/docs/swml/reference/calling/switch) and `cond` in SWML, or per-call logic in the server that returns the document | -| IVR menus | [IVR Menus](../applications/ivr-menus.mdx) | [`prompt`](https://signalwire.com/docs/swml/reference/calling/prompt) and `switch` in SWML, or a conversational [AI agent](https://signalwire.com/docs/swml/reference/calling/ai) | +| Time-based routing | [Time and Condition Routing](../dialplan/time-and-condition-routing.mdx) | [`switch`](https://signalwire.com/docs/swml/reference/calling/switch) and [`cond`](https://signalwire.com/docs/swml/reference/calling/cond) in SWML, or per-call logic in the server that returns the document | +| IVR menus | [IVR Menus](../applications/ivr-menus.mdx) | [`prompt`](https://signalwire.com/docs/swml/reference/calling/prompt) and [`switch`](https://signalwire.com/docs/swml/reference/calling/switch) in SWML, or a conversational [AI agent](https://signalwire.com/docs/swml/reference/calling/ai) | | Voicemail | [Voicemail](../applications/voicemail.mdx) | [Call Flow Builder](https://signalwire.com/docs/call-flow-builder) voicemail node; [`record`](https://signalwire.com/docs/swml/reference/calling/record) in SWML | -| Conferencing | [Conferencing](../applications/conferencing.mdx) | [`join_conference`](https://signalwire.com/docs/swml/reference/calling/join-conference) in SWML; [video rooms](https://signalwire.com/docs/platform/video) with `join_room` | +| Conferencing | [Conferencing](../applications/conferencing.mdx) | [`join_conference`](https://signalwire.com/docs/swml/reference/calling/join-conference) in SWML; [video rooms](https://signalwire.com/docs/platform/video) with [`join_room`](https://signalwire.com/docs/swml/reference/calling/join-room) | | Queues and call center | [Queues: FIFO and Call Center](../applications/queues-fifo-callcenter.mdx) | [`enter_queue`](https://signalwire.com/docs/swml/reference/calling/enter-queue) in SWML; AI agents as first-tier answerers | | Call recording | [Audio Files and Streaming](../media/audio-files-and-streaming.mdx) | [`record_call`](https://signalwire.com/docs/swml/reference/calling/record-call): one line, storage and retrieval included | -| Fax and T.38 | [Fax and T.38](../applications/fax-t38.mdx) | [`send_fax`](https://signalwire.com/docs/swml/reference/calling/send-fax) and `receive_fax` in SWML | +| Fax and T.38 | [Fax and T.38](../applications/fax-t38.mdx) | [`send_fax`](https://signalwire.com/docs/swml/reference/calling/send-fax) and [`receive_fax`](https://signalwire.com/docs/swml/reference/calling/receive-fax) in SWML | | SIP trunks and gateways | [Gateways](../users-endpoints/gateways.mdx) | [SIP trunking](https://signalwire.com/docs/platform/voice/sip/trunking) and [bring your own carrier](https://signalwire.com/docs/platform/voice/sip/bring-your-own-carrier); a [FreeSWITCH Connector](https://signalwire.com/docs/apis/rest/freeswitch-connector) represents your box in the platform | | SIP profiles and registration | [SIP Profiles with Sofia](../users-endpoints/sip-profiles-sofia.mdx) | SIP endpoints and domains as platform resources; the registrar and its TLS edge are operated for you | | WebRTC | [WebRTC with Verto](../users-endpoints/webrtc-verto.mdx), [WebRTC with SIP over WSS](../users-endpoints/webrtc-sip-wss.mdx) | [Browser SDK](https://signalwire.com/docs/browser-sdk) for calling and video in web pages | @@ -38,7 +38,7 @@ Three ways to use this map: | Dynamic configuration | [Dynamic Configuration with mod_xml_curl](../integration/xml-curl.mdx) | The platform's native model: every call can fetch its SWML document from your server | | Scripting | [Scripting Languages](../integration/scripting.mdx), [Scripting APIs](../programming/scripting-apis.mdx) | [Agents SDK and server SDKs](https://signalwire.com/docs/server-sdks/guides/build-ai-agents): call logic as ordinary Python or TypeScript services | | Voice AI agents | No FreeSWITCH equivalent | [SWML `ai`](https://signalwire.com/docs/swml/reference/calling/ai) and the [AI platform](https://signalwire.com/docs/platform/ai): agents that follow steps you define in code | -| TTS and ASR | [ASR and TTS Modules](../module-reference/asr-tts/index.mdx) | [17 TTS vendors](https://signalwire.com/docs/platform/voice/tts) selected by a voice string; [`live_transcribe`](https://signalwire.com/docs/swml/reference/calling/live-transcribe) and `live_translate` | +| TTS and ASR | [ASR and TTS Modules](../module-reference/asr-tts/index.mdx) | [17 TTS vendors](https://signalwire.com/docs/platform/voice/tts) selected by a voice string; [`live_transcribe`](https://signalwire.com/docs/swml/reference/calling/live-transcribe) and [`live_translate`](https://signalwire.com/docs/swml/reference/calling/live-translate) | | SMS | [mod_sms](../module-reference/applications/mod_sms.mdx) | [Messaging API](https://signalwire.com/docs/platform/messaging) with campaign registration handled in the dashboard | | Machine detection | [mod_avmd](../module-reference/applications/mod_avmd.mdx) | [`detect_machine`](https://signalwire.com/docs/swml/reference/calling/detect-machine) in SWML | | HTTP from the dialplan | [mod_curl](../module-reference/applications/mod_curl.mdx) | [`request`](https://signalwire.com/docs/swml/reference/calling/request) in SWML; serverless function calls from AI agents | From af8cf3ea6008057203423afe1414dae14745f236 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 09:11:19 -0500 Subject: [PATCH 04/13] Add "The same build on SignalWire" closers to all six recipes Each Part 10 recipe now ends with a SignalWireCallout containing the working hosted equivalent of the build: SWML documents for the DID-IVR-voicemail attendant, ring/hunt group (connect parallel/serial), and PIN conference; the served-per-call pattern for business-hours routing; a connect-to-platform variant of box-to-box with the FreeSWITCH Connector; and the Calling API POST that replaces originate for click-to-call. SWML method shapes (prompt/prompt_value, switch, connect device lists, record, join_conference, cond) verified against the SWML schema. Build green with strict link checks. Co-Authored-By: Claude Fable 5 --- docs/recipes/recipe-box-to-box.mdx | 17 +++++++++++ docs/recipes/recipe-click-to-call.mdx | 26 ++++++++++++++++ docs/recipes/recipe-conference-pin.mdx | 32 ++++++++++++++++++++ docs/recipes/recipe-did-ivr-voicemail.mdx | 36 +++++++++++++++++++++++ docs/recipes/recipe-ring-group.mdx | 25 ++++++++++++++++ docs/recipes/recipe-time-routing.mdx | 20 +++++++++++++ 6 files changed, 156 insertions(+) diff --git a/docs/recipes/recipe-box-to-box.mdx b/docs/recipes/recipe-box-to-box.mdx index cbdef287..7cde166c 100644 --- a/docs/recipes/recipe-box-to-box.mdx +++ b/docs/recipes/recipe-box-to-box.mdx @@ -280,3 +280,20 @@ Here `$1` is the captured four-digit number without the `8`, so Box A dials `820 Box B receives `2001`. This keeps each box's local numbering plan independent and makes the inter-box link explicit in the dialed string. To preserve the prefix on the wire instead, capture it inside the group (`^(8\d{4})$`) and match the full string on Box B. + + + +The gateway in this chapter is also how a box reaches the hosted platform. Point it at SignalWire instead of a second box, and the far end can be any SIP endpoint, phone number, or AI agent: + +```yaml +- connect: + to: "sip:2001@office-b.example.sip.signalwire.com" +``` + +A FreeSWITCH Connector resource represents each box inside the platform, so hybrid deployments route between self-hosted and hosted the way this recipe routes between boxes. + + diff --git a/docs/recipes/recipe-click-to-call.mdx b/docs/recipes/recipe-click-to-call.mdx index abc40432..f805c222 100644 --- a/docs/recipes/recipe-click-to-call.mdx +++ b/docs/recipes/recipe-click-to-call.mdx @@ -201,3 +201,29 @@ button typically posts to a backend that opens an ESL connection and issues `bgapi originate ...`. See the [Event Socket chapter](/integration/event-socket) for connecting, the inbound vs outbound modes, and consuming the job-result event. + + + +`originate` maps to one POST on SignalWire's REST Calling API: create a call to party A, and hand it a document that connects party B when A answers. + +```bash +curl "https://example.signalwire.com/api/calling/calls" \ + -u "$PROJECT_ID:$API_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "command": "dial", + "params": { + "from": "+15550100", + "to": "+15550111", + "url": "https://example.com/connect-to-b.swml" + } + }' +``` + +The document at `url` runs on the answered leg; a one-method `connect` reaches party B. The click-to-call button becomes an HTTP request from any backend, with no Event Socket session to manage. + + diff --git a/docs/recipes/recipe-conference-pin.mdx b/docs/recipes/recipe-conference-pin.mdx index 3096275c..520c1798 100644 --- a/docs/recipes/recipe-conference-pin.mdx +++ b/docs/recipes/recipe-conference-pin.mdx @@ -269,3 +269,35 @@ To announce the running member count as people arrive, set the first member). See the [profile parameters](../applications/conferencing.mdx#profile-parameters) for the related sound and announcement options. + + + +On hosted SignalWire the PIN check and the room are a few methods of SWML, a JSON/YAML call-control markup: + +```yaml +version: 1.0.0 +sections: + main: + - answer: {} + - prompt: + play: "say:Enter the conference PIN." + max_digits: 4 + - switch: + variable: prompt_value + case: + "7788": + - join_conference: + name: weekly-status + default: + - play: + url: "say:That PIN is not valid. Goodbye." + - hangup: {} +``` + +Entry tones, muting, recording, and moderator behavior are parameters on the same method; there is no conference profile XML and no media server to size. + + diff --git a/docs/recipes/recipe-did-ivr-voicemail.mdx b/docs/recipes/recipe-did-ivr-voicemail.mdx index f1e9c9bc..3b39b8d3 100644 --- a/docs/recipes/recipe-did-ivr-voicemail.mdx +++ b/docs/recipes/recipe-did-ivr-voicemail.mdx @@ -229,3 +229,39 @@ test `hour`, `wday`, or `minute-of-day` on the condition before running `ivr` — the same time fields shown in the shipped `default.xml` `tod_example`. Route the off-hours branch to a `voicemail` extension or a dedicated closed-greeting menu instead of `auto_attendant`. + + + +The auto-attendant this chapter builds is one document in SWML, SignalWire's JSON/YAML call-control markup, assigned to your number in the dashboard. No profiles, no contexts, no menu XML: + +```yaml +version: 1.0.0 +sections: + main: + - answer: {} + - prompt: + play: "say:Thanks for calling. Press 1 for sales, 2 for support." + max_digits: 1 + - switch: + variable: prompt_value + case: + "1": + - connect: + to: "+15550100" + "2": + - connect: + to: "+15550101" + default: + - play: + url: "say:Please leave a message after the tone." + - record: + beep: true +``` + +After a `connect`, the variable `connect_result` reports whether the bridge succeeded, so the no-answer path can fall through to `record` the same way. + + diff --git a/docs/recipes/recipe-ring-group.mdx b/docs/recipes/recipe-ring-group.mdx index 0538ef25..bba44439 100644 --- a/docs/recipes/recipe-ring-group.mdx +++ b/docs/recipes/recipe-ring-group.mdx @@ -251,3 +251,28 @@ answer and stop the hunt. If both legs fail, the caller lands in voicemail. Replace `mycarrier` with the name of a gateway you have defined and registered. The gateway must be configured under a loaded Sofia profile before this extension will work. + + + +Both behaviors are one `connect` in SWML, SignalWire's JSON/YAML call-control markup: `parallel` rings the group at once, `serial` hunts down the list. + +```yaml +version: 1.0.0 +sections: + main: + - answer: {} + - connect: + timeout: 20 + parallel: + - to: "sip:alice@office.example.sip.signalwire.com" + - to: "sip:bob@office.example.sip.signalwire.com" + - to: "+15550142" +``` + +Swap `parallel` for `serial` and the same list hunts in order. Members can be SIP endpoints, phone numbers, or AI agents in any mix. + + diff --git a/docs/recipes/recipe-time-routing.mdx b/docs/recipes/recipe-time-routing.mdx index e6bc7b30..c37f628a 100644 --- a/docs/recipes/recipe-time-routing.mdx +++ b/docs/recipes/recipe-time-routing.mdx @@ -318,3 +318,23 @@ Then in the time router, transfer the open branch to `${open_dest}` and use numbers while each keeps its own operator menu and mailbox. Different lines can also carry different `timezone` values, giving each DID a schedule in its own zone. + + + +On SignalWire the per-call decision lives in the server that returns the document. Your number fetches its SWML (a JSON/YAML call-control markup) on every call, the `mod_xml_curl` pattern, so business hours become ordinary code: + +```python +@app.route("/swml", methods=["POST"]) +def route_call(): + if open_now(): # Mon-Fri 9-5, holidays, all in code you can test + return open_swml # connect to the operator or IVR + return closed_swml # closed greeting, then record a message +``` + +No `strftime` condition syntax to memorize, and the holiday list is a data structure instead of a dialplan edit. + + From e05e4890e99397205c73aad6f7edc7e002fb5fe5 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 09:14:59 -0500 Subject: [PATCH 05/13] Rewrite time-routing recipe callout to use the Server SDK The example now subclasses SWMLService and serves the open/closed document from on_request, per the documented unified Python SDK API; the callout links the Server SDK docs (URL verified live) instead of the SWML overview. Co-Authored-By: Claude Fable 5 --- docs/recipes/recipe-time-routing.mdx | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/recipes/recipe-time-routing.mdx b/docs/recipes/recipe-time-routing.mdx index c37f628a..288743c0 100644 --- a/docs/recipes/recipe-time-routing.mdx +++ b/docs/recipes/recipe-time-routing.mdx @@ -321,20 +321,31 @@ zone. + linkText="See the Server SDK"> -On SignalWire the per-call decision lives in the server that returns the document. Your number fetches its SWML (a JSON/YAML call-control markup) on every call, the `mod_xml_curl` pattern, so business hours become ordinary code: +On SignalWire the per-call decision lives in code. The Server SDK's `SWMLService` builds and serves the call-control document on every call, the `mod_xml_curl` pattern, so business hours become ordinary Python: ```python -@app.route("/swml", methods=["POST"]) -def route_call(): - if open_now(): # Mon-Fri 9-5, holidays, all in code you can test - return open_swml # connect to the operator or IVR - return closed_swml # closed greeting, then record a message +from signalwire import SWMLService + +class BusinessHours(SWMLService): + def on_request(self, request_data=None, callback_path=None): + if open_now(): # Mon-Fri 9-5, holidays: plain Python you can unit test + return {"sections": {"main": [ + {"answer": {}}, + {"connect": {"to": "+15550100"}}, + ]}} + return {"sections": {"main": [ + {"answer": {}}, + {"play": {"url": "say:We are closed. Please leave a message."}}, + {"record": {"beep": True}}, + ]}} + +BusinessHours(name="business-hours").run() ``` -No `strftime` condition syntax to memorize, and the holiday list is a data structure instead of a dialplan edit. +`on_request` runs per call, so the holiday list is a data structure and the open/closed rule is a function with tests, not `strftime` condition syntax. The same SDK ships for TypeScript. From ed44c39c70e8414af0206768f53dafb51f78d56b Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 24 Aug 2026 09:19:08 -0500 Subject: [PATCH 06/13] Give every callout a linkable #signalwire anchor The component now renders id="signalwire" (overridable via an anchor prop) with a hover hash-link on the title and scroll-margin clearing the sticky navbar, so any page's callout is addressable as #signalwire. Co-Authored-By: Claude Fable 5 --- src/components/SignalWireCallout/index.jsx | 19 ++++++++++++++++--- src/css/custom.scss | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/components/SignalWireCallout/index.jsx b/src/components/SignalWireCallout/index.jsx index 3de7a595..2c59ebd6 100644 --- a/src/components/SignalWireCallout/index.jsx +++ b/src/components/SignalWireCallout/index.jsx @@ -12,7 +12,8 @@ const UTM = { * equivalent. Scope rules: maximum one per page, never inside a procedure. * Outbound links carry UTM parameters; utm_content is the page id. */ -export default function SignalWireCallout({ title, href, page, linkText, children }) { +export default function SignalWireCallout({ title, href, page, linkText, anchor, children }) { + const id = anchor || "signalwire"; const url = new URL(href); for (const [key, value] of Object.entries(UTM)) { url.searchParams.set(key, value); @@ -21,9 +22,21 @@ export default function SignalWireCallout({ title, href, page, linkText, childre url.searchParams.set("utm_content", page); } return ( -