Variables
SWML provides a variable system for accessing call or message information, storing intermediate state, and passing data between sections. This page covers how to use variables: syntax, scopes, accessing nested fields, and deployment-mode differences.
For the authoritative field-by-field reference of what each scope contains, see the per-flavor overviews:
- Calling webhook and variable payload —
call,params,vars,envs - Messaging webhook and variable payload —
message,params,vars
For JavaScript expressions on top of variables, see Expressions. For template transformation functions, see Template Functions.
Syntax
Wrap a variable name in ${...} or %{...} anywhere inside a string value, and SignalWire
substitutes the current value when the script runs. Use it to personalize a greeting with the
caller’s number, pass a request body through to your backend, or pick a reply based on the
inbound message body.
The two flavors of SWML accept slightly different forms.
Calling
In a Calling document, ${...} and %{...} are interchangeable — pick whichever reads more
naturally in your YAML or JSON.
Reference a value. Use a plain path like ${call.from} or %{vars.user_choice}. Works
for any field on call, params, envs, or vars. If the path is valid but the value isn’t
set, the placeholder resolves to an empty string.
If the placeholder body isn’t a plain path — for example, it includes operators, method calls, or other JavaScript — it’s evaluated as a JavaScript expression instead. See Expressions.
Messaging
A Messaging document uses %{...} only.
Reference a value. Use a plain path like %{message.from} or %{vars.reply_message_id}.
Works for any field on message, params, or vars. If the path is valid but the value
isn’t set, the placeholder resolves to an empty string.
Variable scopes
The variables available at runtime are the same fields delivered on the inbound webhook payload
for each SWML flavor. See the
Calling webhook and variable payload and the
Messaging webhook and variable payload for the
authoritative list of scopes (call / message, params, vars, envs) and every field
inside them.
Accessing nested data
Variables can hold simple values, nested objects, or arrays. Use dot notation (.) for object
properties and bracket notation ([], zero-based) for array elements. The patterns below work
identically inside ${...} and %{...}; the examples use calling syntax and the
set method to seed the data.
The same patterns apply in messaging — for example, %{message.media[0].url} accesses the
first media attachment’s URL.
Deployment modes
SWML can be hosted in two places, which affects how variable values get into your script.
Serverless (Dashboard-hosted)
The SWML document lives in the SignalWire Dashboard. SignalWire evaluates the placeholders against the live runtime context — no HTTP fetch is involved.
Server-based (external URL)
SignalWire POSTs the runtime context to your server and your server returns the SWML document in response (see the Calling or Messaging payload reference for the request shape). You have two ways to use the variables:
1. Return SWML with placeholders. SignalWire substitutes at runtime — exactly the same syntax used in serverless mode. Best when you just need to interpolate values into otherwise-static SWML.
2. Substitute server-side before responding. Read variables from the request body in your server code, then build a SWML document with the values already filled in. Best when you need logic, transformations, or external lookups that can’t be expressed as a placeholder.
The ${...} in the example below is JavaScript template-literal syntax, not SWML
variable expansion — it’s interpolated by Node.js before the response is sent.
See the Deployment Guide for complete server setup instructions.