> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# 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:

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.

The body of the reply message.

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.

An object containing the properties below.

Text body of the outbound message. Required when `media` is not set.

Array of media URLs to attach. Converts the message to MMS. Maximum 8 attachments. Required if
`body` is not present.

Destination phone number in E.164 format.

Sending phone number or short code. Must be owned by your project and have messaging capability.

URL to receive delivery status callbacks for the outbound reply message. See
[Status callbacks](#status-callbacks) below.

Branch the reply body on a variable's value — for keyword-driven replies.
The matched `case` (or `default`) provides the reply body.

An object with a single `switch` property.

An object that accepts the properties below.

Variable path to match. Specified without the `%{}` wrapper (e.g. `message.body`).

Transform to apply to the value before matching. One of `lowercase`, `uppercase`, `trim`,
`lowercase_trim`, or `uppercase_trim`.

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.

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.

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.).

ID of the outbound message created by the successful reply. Absent when
`reply_result` is `failed`.

## **Status callbacks**

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/messages/webhooks/message-status-callback)
webhook page for the full field reference and the list of possible `status` values.

## **Examples**

### Reply with body

```yaml
version: 1.0.0
sections:
  main:
    - reply:
        body: "Thanks for your message!"
```

```json
{
  "version": "1.0.0",
  "sections": {
    "main": [
      {
        "reply": {
          "body": "Thanks for your message!"
        }
      }
    ]
  }
}
```

### Reply with media (MMS)

```yaml
version: 1.0.0
sections:
  main:
    - reply:
        body: "Here's the document you requested"
        media:
          - "https://example.com/document.pdf"
```

```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
version: 1.0.0
sections:
  main:
    - reply:
        body: "Your order is confirmed"
        status_url: "https://example.com/status"
```

```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
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
{
  "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
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
{
  "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
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
{
  "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}"
        }
      }
    ]
  }
}
```