> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # reply > Create and send an outbound message in response to an inbound message. Create and send an outbound message in response to the inbound message. `reply` accepts three shapes: a string shorthand, an object with body/media/routing fields, or an inline `switch` that branches the reply body on a variable's value. `reply` does **not** end execution — subsequent steps in the section continue to run after the reply is queued. ## **Properties** `reply` accepts one of three shapes — use whichever fits the document shape: #### String shorthand A single string used as the reply body. The reply is sent to the inbound message's `from` number, using the inbound `to` as the sender. **`reply`** `string` — required The body of the reply message. --- #### Object Full control over the reply — set the body, attach media, override the routing fields, or configure a delivery status callback. At least one of `body` or `media` must be present. **`reply`** `object` — required An object containing the properties below. --- **`reply.body`** `string` Text body of the outbound message. Required when `media` is not set. --- **`reply.media`** `string[]` Array of media URLs to attach. Converts the message to MMS. Maximum 8 attachments. Required if `body` is not present. --- **`reply.to`** `string` — default: message.from Destination phone number in E.164 format. --- **`reply.from`** `string` — default: message.to Sending phone number or short code. Must be owned by your project and have messaging capability. --- **`reply.status_url`** `string` URL to receive delivery status callbacks for the outbound reply message. See [Status callbacks](#status-callbacks) below. --- #### Inline switch Branch the reply body on a variable's value — for keyword-driven replies. The matched `case` (or `default`) provides the reply body. **`reply`** `object` — required An object with a single `switch` property. --- **`reply.switch`** `object` — required An object that accepts the properties below. --- **`reply.switch.variable`** `string` — required Variable path to match. Specified without the `%{}` wrapper (e.g. `message.body`). --- **`reply.switch.transform`** `string` Transform to apply to the value before matching. One of `lowercase`, `uppercase`, `trim`, `lowercase_trim`, or `uppercase_trim`. --- **`reply.switch.case`** `object` — required Map of values to reply outcomes. Each entry's value is either: * a **string** — used as the reply body, sent back to the original sender as SMS, or * a **full reply object** with `body`, `media`, `to`, `from`, `status_url` — for cases that need media, a different destination, or a per-branch `status_url`. `%{…}` placeholders inside the matched value are expanded before the reply is sent. --- **`reply.switch.default`** `string | object` Fallback used when no `case` value matches. Accepts the same string-or-reply-object shape as a `case` value. If omitted and no case matches, the `reply` step fails and execution stops. --- When using an inline `switch`, do not set `body`, `media`, `to`, `from`, or `status_url` directly on the same `reply` — put them inside each `case` value (or `default`) instead. ## **Variables** `reply` writes these variables into the script context after it runs. Read them with the `%{variable}` syntax in subsequent steps. When `reply` is called multiple times in a single document, both variables reflect the most recent reply. **`reply_result`** `string` Outcome of the reply attempt. `queued` when the outbound message was accepted for delivery, `failed` when validation or delivery rejected it (invalid `from`/`to`, missing body and media, character limit exceeded, missing messaging capability, inactive campaign, etc.). --- **`reply_message_id`** `string` ID of the outbound message created by the successful reply. Absent when `reply_result` is `failed`. --- ## **Status callbacks** > **Status callbacks are advisory** > > Status callbacks are asynchronous, best-effort HTTP notifications: delivery can be delayed or fail silently — if your server is unreachable, the callback simply never arrives. Don't gate time-critical or business-critical actions solely on receiving one. Confirm state via the REST API before acting, or use a transport with visible failure modes — see [Status callback reliability](/docs/platform/webhooks#status-callback-reliability). The `status_url` on `reply` registers a delivery status callback for the **outbound reply message** — not for the inbound message that triggered the SWML document. It behaves the same way as the status callback on any other outbound message sent through SignalWire. * Fires as the outbound reply moves through delivery states. * Callback delivery is independent of SWML execution: the SWML document completes as soon as the reply is accepted (`reply_result: "queued"`); delivery-state callbacks fire afterwards. * If `reply` is called multiple times in a single document, each reply's `status_url` is registered independently for its own outbound message. When `status_url` is set, SignalWire sends an HTTP `POST` to that URL each time the outbound reply transitions to a new state. The callback uses the same payload as other outbound messages sent through SignalWire. See the [Message status callback](/docs/apis/rest/webhooks/message-status-callback) webhook page for the full field reference and the list of possible `status` values. ## **Examples** ### Reply with body #### YAML ```yaml version: 1.0.0 sections: main: - reply: body: "Thanks for your message!" ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "body": "Thanks for your message!" } } ] } } ``` ### Reply with media (MMS) #### YAML ```yaml version: 1.0.0 sections: main: - reply: body: "Here's the document you requested" media: - "https://example.com/document.pdf" ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "body": "Here's the document you requested", "media": [ "https://example.com/document.pdf" ] } } ] } } ``` ### Reply with a status callback URL #### YAML ```yaml version: 1.0.0 sections: main: - reply: body: "Your order is confirmed" status_url: "https://example.com/status" ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "body": "Your order is confirmed", "status_url": "https://example.com/status" } } ] } } ``` ### Keyword-driven reply with inline switch The inline `switch` form branches the reply body on a variable's value — typically the inbound `message.body`. #### YAML ```yaml version: 1.0.0 sections: main: - reply: switch: variable: message.body transform: lowercase_trim case: help: "Reply STOP to unsubscribe, or visit https://example.com/help." stop: "You've been unsubscribed." start: "Welcome back!" default: "Thanks for your message!" ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "switch": { "variable": "message.body", "transform": "lowercase_trim", "case": { "help": "Reply STOP to unsubscribe, or visit https://example.com/help.", "stop": "You've been unsubscribed.", "start": "Welcome back!" }, "default": "Thanks for your message!" } } } ] } } ``` ### Per-case media and routing with inline switch When a case needs more than a body string — different media, a different destination, or a per-branch `status_url` — supply a full reply object for that case instead of a bare string. #### YAML ```yaml version: 1.0.0 sections: main: - reply: switch: variable: message.body transform: lowercase_trim case: menu: body: "Here's our menu." media: - "https://example.com/menu.pdf" directions: body: "Tap below for directions." media: - "https://example.com/map.jpg" agent: body: "Connecting you with a human — they'll text from a different number." from: "+15559876543" default: "Reply MENU, DIRECTIONS, or AGENT." ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "switch": { "variable": "message.body", "transform": "lowercase_trim", "case": { "menu": { "body": "Here's our menu.", "media": ["https://example.com/menu.pdf"] }, "directions": { "body": "Tap below for directions.", "media": ["https://example.com/map.jpg"] }, "agent": { "body": "Connecting you with a human — they'll text from a different number.", "from": "+15559876543" } }, "default": "Reply MENU, DIRECTIONS, or AGENT." } } } ] } } ``` ### Forward an inbound message to another number #### YAML ```yaml version: 1.0.0 sections: main: - reply: to: "+12223334444" from: "+15559876543" body: "Your number %{message.to} got a message from %{message.from}! The body was: %{message.body}" ``` #### JSON ```json { "version": "1.0.0", "sections": { "main": [ { "reply": { "to": "+12223334444", "from": "+15559876543", "body": "Your number %{message.to} got a message from %{message.from}! The body was: %{message.body}" } } ] } } ``` > Create and send an outbound message in response to an inbound message.