# SWML Overview SignalWire Markup Language (SWML) allows you to build RELAY applications using a descriptive format which doesnt necessarily require additional infrastructure such as your own server. You can think of SWML as the RELAY equivalent of [Compatibility XML](compatibility-api/xml/index.mdx). It is, however, expressed in JSON / YAML using the statements and methods defined here. Statements are used for general control flow and state management. Methods are used for call control. SWML Scripts can be written and saved in the [RELAY Dashboard](https://my.signalwire.com/relay-bins) of your SignalWire Space. Heres a basic SWML document: yaml andJson version: 1.0.0 sections: main: - record - play: say:Hello, world! - hangup ## **Document Fetching** A SWML script is fetched as follows: 1. SignalWire receives a call (e.g., a PSTN call) to one of the numbers configured to use SWML. 2. SignalWire sends a POST request to the configured webhook, with a body containing the set of currently defined [script variables](#variables) (initially empty) and the current call object: json { call: { state: created, type: sip, from: sip:+15551231234@example.com, to: sip:+15553214321@example.com, headers: [ { name: X-Header-1, value: X-Header-1-Value }, { name: X-Header-2, value: X-Header-2-Value } ] }, vars: { customer_script_var_1: customer_script_var_1_value, customer_script_var_2: customer_script_var_2_value }, params: { param_1: param_1_value, param_2: param_2_value } } 3. The server replies with a SWML script to execute, using application/json or application/yaml or text/x-yaml as content-type. ## **Versioning** At the top level of a script is a version field, which is a string containing a semantic version of the document schema. Suggested use is for a MAJOR version to reflect breaking changes where a script may not operate correctly without changes (i.e., renaming, refactoring, or new required parameters for existing methods). A MINOR version can be used as new methods or new optional fields for existing methods are introduced. A PATCH version can be used to reflect only the most minor bug fixes which still have some impact on the schema. ## **Document Execution** Every SWML script contains a sections field that is a mapping of named sections for execution. The main section is always executed first. There must always be a main section in the document. The [transfer](./methods/transfer.mdx) statement is used to transfer the call execution to a new URL. Each section is an array of strings or objects. Strings can be used for methods that do not require parameters, such as [answer](./methods/answer.mdx), [hangup](./methods/hangup.mdx), or [denoise](./methods/denoise.mdx). Use objects to execute methods with parameters. Each string or object in the sections array is executed in order until the section is completed. If there are no more methods to execute, the call ends. ## **Expression Evaluation with JavaScript** All text wrapped in %{} is evaluated as JavaScript or as a plain variable substitution. ## **Variables and Call Parameters** {#variables} All variables and call parameters are delivered in the POST body to the URL in transfer and execute. Use the [set](./methods/set.mdx) and [unset](./methods/unset.mdx) statements to set or delete variables. All variables can be referenced inside %{} JavaScript expressions in the vars. JavaScript object. Variables can not be permanently changed inside JavaScript expressions. All Call object parameters are referenceable inside JavaScript expressions. For example %{call.from} or %{call.headers.X-Customer-ID}. Call object parameters are read only, and they are: | Parameter | Type | Description | |-:||-| | call_id | string | A unique identifier for the call. | | node_id | string | A unique identifier for the node handling the call. | | segment_id | string | A unique identifier for the segment. | | call_state | string | The current state of the call. | | direction | string | The direction of this call.
Possible values: inbound, outbound | | type | string | The type of call.
Possible values: sip, phone | | from | string | The number/uri that initiated this call. | | to | string | The number/uri of the destination of this call. | | headers | object[] | The headers associated with this call. | | headers.name | string | The name of the header. | | headers.value | string | The value of the header. | | project_id | string | The Project ID this call belongs to. | | space_id | string | The Space ID this call belongs to. | All variables are global, and their scope corresponds to the scope of the call (_not_ of the section, and _not_ of the script). ## **Script Example** In this example, the main section is executed to answer the call, play two files, then prompt for DTMF input. If 1 is pressed, the flow loops back to the welcome message. Otherwise, the call is hung up. yaml andJson version: 1.0.0 sections: main: - answer - execute: get-input get-input: - prompt: play: https://example.com/welcome.mp3 - switch: variable: prompt_value case: 1: - play: say: Thats correct! - hangup default: - play: say: Bye! - hangup ## **Implementing Subroutines or Integrations** The [execute](./methods/execute.mdx) statement provides a mechanism for calling subroutines. A subroutine is implemented as a section in the document that can optionally accept named parameters and return a result or can be hosted by a server. The subroutine may optionally be implemented as an object with meta and code fields to add user-defined data and the code to execute, respectively. ### JSON Subroutine in Script json { version: 1.0.0, sections: { main: [ { execute: { params: { file: https://example.com/foo.wav }, meta: { x: 100, y: 100 }, dest: my_subroutine } }, { execute: { params: { file: https://example.com/bar.wav }, dest: my_subroutine } } ], my_subroutine: [{ play: %{params.file} }, { return: 1 }] } } ### JSON Subroutine Hosted by Server This operates similarly to the previous example, except the script will execute a URL that will reply with the following document: json { version: 1.0.0, sections: { main: [{ play: %{params.file} }, { return: 1 }] } } ## **Executing SWML from a RELAY application** The following example is a node.js application that listens on a relay application named swml, and then transfers the call to a relay ML script. The script may be defined in the request or may specify a URL that will return the document in response to a post request to it. You must map a phone number or domain app to the swml application name in your [dashboard](https://my.signalwire.com/phone_numbers). javascript const { Voice } = require(@signalwire/realtime-api); var script = version: 1.0.0 sections: main: - answer - play: - silence:2 - say:Please hold while we connect you - connect: to: +15551231234 from: +15553214321; javascript const client = new Voice.Client({ project: