# Payload reference

Reference for the `Payload` message used by [`Notify`](/developer/api-reference/messaging-api-v2/notify/) when sending through any non-email channel (push, SMS, Telegram, Kakao, LINE, Viber, WhatsApp).

<Aside type="note">
For email, see the [Email payload reference](/developer/api-reference/messaging-api-v2/email-payload-reference/).
</Aside>

## Payload

- `preset` (string): [push preset](/product/content/push-presets/) code (format `XXXXX-XXXXX`) to apply to this message.
- `sms_preset` (string): code (format `XXXXX-XXXXX`) of a saved [SMS preset](/product/content/sms-presets/). Its per-locale text is resolved into each locale's [`sms.body`](#sms-sms). An inline `sms.body` for a given locale overrides the preset for that locale. The preset must belong to the same application as the message.
- `content` ([`LocalizedContent`](#localizedcontent)): message content. Mutually exclusive with `silent`.
- `silent` (bool): send a silent (data-only) push. Mutually exclusive with `content`.
- `custom_data` (object): free-form JSON forwarded to the client SDK as the `u` parameter.
- `open_action` ([`OpenAction`](#openaction)): action triggered when the user opens the notification.
- `open_actions` (map&lt;Platform, `OpenAction`&gt;): per-platform override of `open_action`. Key is a numeric `Platform` enum value.
- `voip_push` (bool): iOS VoIP notification.

```json
{
  "payload": {
    "preset": "XXXXX-XXXXX",
    "content": { "localized_content": { "default": { "ios": { "title": "Hello", "body": "Tap to view" } } } },
    "custom_data": { "order_id": "42" },
    "open_action": { "link": { "url": "https://example.com/promo" } }
  }
}
```

## LocalizedContent

Maps locale code → per-platform content. Keys are [ISO 639-1](https://www.loc.gov/standards/iso639-2/php/code_list.php) two-letter codes (for example, `"en"`, `"es"`) plus the special key `"default"` for a catch-all translation. The exceptions to ISO 639-1 are `"zh-Hant"` and `"zh-Hans"` for Traditional and Simplified Chinese.

```json
{
  "localized_content": {
    "default": {
      "ios":     { "title": "Hello", "body": "Tap to view" },
      "android": { "title": "Hello", "body": "Tap to view" }
    },
    "es": {
      "ios":     { "title": "Hola",  "body": "Toca para ver" },
      "android": { "title": "Hola",  "body": "Toca para ver" }
    }
  }
}
```

### Locale selection for a device

Content delivered to a device is picked in this order:

1. Exact match on the device's language.
2. Key `"default"`.
3. Key `"en"`.
4. Any other locale present in the map.

Provide at least one of `"default"` or `"en"` so every device has a deterministic fallback. If you do not expect per-locale variants, send only `"default"`.

Each locale entry is a `Content` object with optional per-platform blocks. Only fill in the platforms you target.

| Platform block | Channel |
|---|---|
| `ios` | iOS push |
| `android` | Android (FCM) push |
| `huawei_android` | Huawei Android push |
| `baidu_android` | Baidu Android push |
| `mac_os` | macOS push |
| `amazon` | Amazon (ADM) push |
| `safari` | Safari web push |
| `chrome` | Chrome web push |
| `firefox` | Firefox web push |
| `ie` | Internet Explorer web push |
| `windows` | Windows push (tile / toast / badge) |
| `telegram` | Telegram message |
| `kakao` | Kakao message |
| `line` | LINE message |
| `viber` | Viber message |
| `whatsapp` | WhatsApp message |
| `sms` | SMS message |

## Common push fields

These fields are shared by `ios`, `android`, `huawei_android`, `baidu_android`, `mac_os`, `amazon`, `safari`, `chrome`, and `firefox` blocks (support varies. Unused fields are ignored by the relevant platform).

- `title` (string): notification title.
- `body` (string): notification body.
- `time_to_live` (duration, e.g. `"3600s"`): how long the push server should retain the notification for an offline device.
- `sound` (string): sound file name.
- `sound_enabled` (bool): enable or suppress sound.
- `badges` (string): badge count (iOS) or analogue.
- `root_params` (object): raw platform-specific payload overrides.
- `inbox` ([`Inbox`](#inbox)): [Message Inbox](/developer/guides/message-inbox/mobile-message-inbox/) entry.

```json
{
  "android": {
    "title": "Hello",
    "body": "Tap to view",
    "time_to_live": "3600s",
    "sound": "default",
    "sound_enabled": true,
    "badges": "+1"
  }
}
```

## iOS (`ios`)

- `subtitle` (string): iOS notification subtitle.
- `is_critical` (bool): critical alert (requires entitlement).
- `attachment` (string): URL of a media attachment.
- `thread_id` (string): thread identifier for grouped notifications.
- `trim_content` (bool): trim content to fit.
- `category_id` (string): `UNNotificationCategory` identifier for interactive actions.
- `interruption_level` (string): `passive`, `active`, `time-sensitive`, or `critical`.
- `collapse_id` (string): APNs collapse identifier. Notifications with the same `collapse_id` replace each other on the device.

```json
{
  "ios": {
    "title": "Hello",
    "body": "Tap to view",
    "subtitle": "New update",
    "attachment": "https://cdn.example.com/image.png",
    "interruption_level": "active",
    "thread_id": "promo"
  }
}
```

## Android (`android`, `huawei_android`, `baidu_android`)

- `icon` (string): notification small icon.
- `banner` (string): big-picture URL.
- `delivery_priority` (`NORMAL` | `HIGH`): FCM delivery priority.
- `vibration` (bool): vibration on receive.
- `led_color` (string, hex): notification LED color.
- `icon_background_color` (string, hex): icon background color.
- `show_on_lockscreen` (bool): show on the lock screen.
- `custom_icon` (string): URL of a custom icon.
- `priority` ([`NotificationPriority`](#notificationpriority-enum)): in-tray priority.
- `group_id` (string): notification group key.
- `collapse_key` (string): FCM collapse key. Notifications with the same `collapse_key` replace each other while the device is offline.

```json
{
  "android": {
    "title": "Hello",
    "body": "Tap to view",
    "icon": "ic_notification",
    "banner": "https://cdn.example.com/banner.png",
    "led_color": "#FF0000",
    "priority": "PRIORITY_HIGH",
    "delivery_priority": "HIGH"
  }
}
```

## macOS (`mac_os`)

Uses the common push fields plus `subtitle` and `action` (URL opened when the user clicks the notification).

```json
{
  "mac_os": {
    "title": "Hello",
    "body": "Tap to view",
    "subtitle": "New update",
    "action": "https://example.com/promo"
  }
}
```

## Amazon (`amazon`)

Uses the common push fields plus `custom_icon` and `priority` ([`NotificationPriority`](#notificationpriority-enum)).

```json
{
  "amazon": {
    "title": "Hello",
    "body": "Tap to view",
    "custom_icon": "https://cdn.example.com/icon.png",
    "priority": "PRIORITY_HIGH"
  }
}
```

## Safari (`safari`)

- `action` (string): URL opened when the user clicks the notification.
- `url_arguments` (array of string): Safari URL arguments substituted into the Web Push URL template.

```json
{
  "safari": {
    "title": "Hello",
    "body": "Tap to view",
    "action": "https://example.com/promo",
    "url_arguments": ["promo", "2026"]
  }
}
```

## Chrome (`chrome`)

- `icon`, `image` (string): small icon and large image URLs.
- `duration` (duration): auto-close timer.
- `button_text1` / `button_url1`, `button_text2` / `button_url2`: up to two action buttons.

```json
{
  "chrome": {
    "title": "Hello",
    "body": "Tap to view",
    "icon": "https://cdn.example.com/icon.png",
    "image": "https://cdn.example.com/banner.png",
    "duration": "20s",
    "button_text1": "Open",
    "button_url1": "https://example.com/promo"
  }
}
```

## Firefox (`firefox`)

Uses only `title`, `body`, `icon`, `root_params`, and `inbox`.

```json
{
  "firefox": {
    "title": "Hello",
    "body": "Tap to view",
    "icon": "https://cdn.example.com/icon.png"
  }
}
```

## Windows (`windows`)

Windows uses a different shape:

```json
{
  "windows": {
    "type": "TOAST",
    "template": { "title": "Hello", "body": "Tap to view" },
    "tag": "promo",
    "cache": true,
    "time_to_live": "3600s"
  }
}
```

- `type` is `TILE`, `TOAST`, or `BADGE`.
- `template` (structured) or `raw` (`{ "content": "<raw xml>" }`) — exactly one.

## Telegram (`telegram`)

- `body` (string): message text.
- `content_variables` (string): JSON-stringified variables for the bot-side template.

```json
{
  "telegram": {
    "body": "Hello from Pushwoosh",
    "content_variables": "{\"name\":\"John\"}"
  }
}
```

## Kakao (`kakao`)

- `content` (string): message content.
- `template` (string): approved template code.
- `content_variables` (string): JSON-stringified template variable bindings.

```json
{
  "kakao": {
    "content": "Hello from Pushwoosh",
    "template": "welcome_v1",
    "content_variables": "{\"name\":\"John\"}"
  }
}
```

## LINE (`line`)

- `content` (string): plain text body.
- `template` (string): code of a LINE template configured in the Pushwoosh Control Panel (used to send image, carousel, or flex messages). For rich content, pre-configure the template in the Control Panel and reference it here.

At least one of `content` or `template` must be set.

```json
{
  "line": {
    "content": "Hello from Pushwoosh",
    "template": "promo_carousel"
  }
}
```

## Viber (`viber`)

A Viber message is either a free-text body or a pre-approved transactional template (Omni Messaging / MStat) referenced by id and language.

- `body` (string): plain text message. Required when `template_id` is not set.
- `template_id` (string): id of a pre-approved transactional template. When set, it takes precedence over `body`.
- `template_lang` (string): template locale. Required when `template_id` is set.
- `template_params` (map&lt;string, string&gt;): key/value bindings substituted into the template, e.g. `{ "name": "John", "code": "123456" }`.
- `all_devices` (bool): `false` (default) delivers to the user's primary device only; `true` delivers to all of the user's devices.

At least one of `body` or `template_id` must be set. When `template_id` is set, `template_lang` is required.

Address Viber recipients as hwids in the form `viber:<phone>` (E.164), for example `viber:+1234567890`.

Plain text:

```json
{
  "viber": {
    "body": "Hello from Pushwoosh"
  }
}
```

Transactional template:

```json
{
  "viber": {
    "template_id": "e3dec4a0-c063-4b0f-96d5-cf9d629a7abe",
    "template_lang": "en",
    "template_params": {
      "name": "John",
      "code": "123456",
      "expires_in": "5 minutes"
    },
    "all_devices": false
  }
}
```

## WhatsApp (`whatsapp`)

WhatsApp messages go through Meta and are subject to Meta's messaging rules. The key split is between free-form text (only delivered inside the 24-hour customer service window opened by an inbound message from the user) and approved templates (required for outbound initiation and for any message outside the 24-hour window).

- `content` (string): free-form message text. Delivered by Meta only inside the 24-hour window.
- `content_id` (string): name of a pre-approved Meta template (e.g. `"hello_world"`). Required for outbound initiation or any message outside the 24-hour window.
- `language` (string): template locale that must exactly match the locale approved in Meta (e.g. `"en_US"`, `"en_GB"`). Only meaningful together with `content_id`. This is independent of the outer `LocalizedContent` key. The outer key selects content for a device, and `language` selects the Meta-template locale for that content.
- `content_variables` (string): JSON object mapping body placeholders, e.g. `"{\"1\":\"John\"}"`.
- `button_url_variables` (string): JSON object mapping button-URL placeholders keyed by button index, e.g. `"{\"0\":\"https://...\"}"`.
- `header_variables` (string): JSON object mapping header placeholders keyed by type, e.g. `"{\"image\":\"https://...\"}"`.

At least one of `content` or `content_id` must be set.

```json
{
  "whatsapp": {
    "content_id": "hello_world",
    "language": "en_US",
    "content_variables": "{\"1\":\"John\"}"
  }
}
```

## SMS (`sms`)

SMS has its own platform block inside each locale's [`Content`](#localizedcontent), alongside `ios`, `android`, and the other messaging channels.

- `body` (string): SMS text for the locale. Required when the `sms` block is present.

There are two ways to supply the text:

- **Inline** — set `sms.body` per locale in `localized_content`.
- **From a preset** — set the payload-level [`sms_preset`](#payload) to the code (format `XXXXX-XXXXX`) of a saved [SMS preset](/product/content/sms-presets/). Its per-locale content is resolved into `sms.body` for each locale the preset defines. An inline `sms.body` for a locale overrides the preset for that locale, so you can reuse a preset and still tweak individual languages.

```json
{
  "payload": {
    "sms_preset": "XXXXX-XXXXX",
    "content": {
      "localized_content": {
        "default": { "sms": { "body": "Your order has shipped." } },
        "es":      { "sms": { "body": "Tu pedido ha sido enviado." } }
      }
    }
  }
}
```

## OpenAction
Defines the action performed when the user opens the message.

Exactly one of:

- `rich_media` ([`RichMedia`](#richmedia)): open a [Rich Media](/product/content/in-apps/) page.
- `deep_link`: open a deep link: `{ "code": "flow-code", "params": { "key": "value" } }`.
- `link` ([`Link`](#link)): open a URL.

```json
{
  "open_action": {
    "deep_link": { "code": "flow-code", "params": { "promo": "summer" } }
  }
}
```

The deeplink URL and `params` values support [Liquid personalization](/developer/guides/personalization/liquid-templates/) syntax — expressions are resolved before the deep link is opened.

### RichMedia


```json
{ "code": "XXXXX-XXXXX" }        // by Rich Media code
{ "url":  "https://..." }        // by remote URL
```

### Link


```json
{
  "url": "https://example.com/promo",
  "shortener": "BITLY"
}
```

`shortener` is `NONE` (default) or `BITLY`.

## Inbox

Configures how the message appears in Message Inbox.

```json
{
  "image_url": "https://cdn.example.com/inbox.png",
  "expiration_date": "2026-05-15T00:00:00Z"
}
```

- `image_url` (string): image shown in the inbox entry.
- `expiration_date` (timestamp): when the entry is removed from the inbox.

## NotificationPriority enum
Controls notification priority on the target device, from `PRIORITY_MIN` (lowest) to `PRIORITY_MAX` (highest).

- `PRIORITY_UNSPECIFIED`
- `PRIORITY_MIN`
- `PRIORITY_LOW`
- `PRIORITY_DEFAULT`
- `PRIORITY_HIGH`
- `PRIORITY_MAX`

<Aside type="caution">
Always send `priority` as one of the string values above. The API also accepts the enum's numeric equivalents (1-5, matching the order above), but that mapping is an internal protobuf detail, not a supported contract — don't rely on it.

An unrecognized `priority` value (a misspelled string or an out-of-range number) is not rejected: the API silently drops it, and the notification is sent with no `priority` field at all instead of returning an error.
</Aside>

## Example: Send a push to a segment

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "application": "XXXXX-XXXXX",
      "platforms": ["IOS", "ANDROID"],
      "code": "active_users",
      "payload": {
        "content": {
          "localized_content": {
            "en": {
              "ios":     { "title": "Hello",   "body": "Hello, world!" },
              "android": { "title": "Hello",   "body": "Hello, world!" }
            },
            "es": {
              "ios":     { "title": "¡Hola!",  "body": "¡Hola, mundo!" },
              "android": { "title": "¡Hola!",  "body": "¡Hola, mundo!" }
            }
          }
        },
        "open_action": { "link": { "url": "https://example.com/promo" } }
      },
      "schedule":     { "at": "2026-05-01T12:00:00Z" },
      "message_type": "MESSAGE_TYPE_MARKETING"
    }
  }'
```

## Example: Transactional push by user IDs

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactional": {
      "application": "XXXXX-XXXXX",
      "platforms": ["IOS", "ANDROID"],
      "users": { "list": ["customer-42"] },
      "payload": {
        "content": {
          "localized_content": {
            "default": {
              "ios":     { "title": "Your order", "body": "Order #42 has shipped." },
              "android": { "title": "Your order", "body": "Order #42 has shipped." }
            }
          }
        },
        "custom_data": { "order_id": "42" }
      },
      "schedule":     { "at": "2026-05-01T12:00:00Z" },
      "message_type": "MESSAGE_TYPE_TRANSACTIONAL"
    }
  }'
```