Skip to content

Payload reference

Reference for the Payload message used by Notify when sending through any non-email channel (push, SMS, Telegram, Kakao, LINE, Viber, WhatsApp, Facebook Messenger).

  • preset (string): push preset code (format XXXXX-XXXXX) to apply to this message.
  • sms_preset (string): code (format XXXXX-XXXXX) of a saved SMS preset. Its per-locale text is resolved into each locale’s sms.body. 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): message content. Mutually exclusive with silent.
  • silent (bool): send a silent (data-only) push to every platform. Mutually exclusive with content. To make only some platforms silent, set silent inside content for iOS or Android instead.
  • custom_data (object): free-form JSON forwarded to the client SDK as the u parameter.
  • open_action (OpenAction): action triggered when the user opens the notification.
  • open_actions (map<Platform, OpenAction>): per-platform override of open_action. Key is a numeric Platform enum value.
  • voip_push (bool): iOS VoIP notification.
{
"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

Anchor link to

Maps locale code → per-platform content. Keys are ISO 639-1 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.

{
"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

Anchor link to

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 blockChannel
iosiOS push
androidAndroid (FCM) push
huawei_androidHuawei Android push
mac_osmacOS push
amazonAmazon (ADM) push
safariSafari web push
chromeChrome web push
firefoxFirefox web push
ieInternet Explorer web push
windowsWindows push (tile / toast / badge)
telegramTelegram message
kakaoKakao message
lineLINE message
viberViber message
whatsappWhatsApp message
fb_messengerFacebook Messenger message
smsSMS message

Common push fields

Anchor link to

These fields are shared by ios, android, huawei_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): Message Inbox entry.
{
"android": {
"title": "Hello",
"body": "Tap to view",
"time_to_live": "3600s",
"sound": "default",
"sound_enabled": true,
"badges": "+1"
}
}
  • 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.
  • silent (bool): send the iOS push as silent (data-only), while other platforms in the same message get a regular notification. Set inside content, so it works together with it. To make every platform silent, use the top-level silent instead, which replaces content. Set it in any locale to apply it to every locale.
{
"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)

Anchor link to
  • 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): 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.
  • silent (bool): send the push to this platform as silent (data-only), while other platforms in the same message get a regular notification. Set inside content, so it works together with it. To make every platform silent, use the top-level silent instead, which replaces content. Set it in any locale to apply it to every locale. The baidu_android block also accepts silent, with the same behavior.
{
"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)

Anchor link to

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

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

Amazon (amazon)

Anchor link to

Uses the common push fields plus custom_icon and priority (NotificationPriority).

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

Safari (safari)

Anchor link to
  • 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.
{
"safari": {
"title": "Hello",
"body": "Tap to view",
"action": "https://example.com/promo",
"url_arguments": ["promo", "2026"]
}
}

Chrome (chrome)

Anchor link to
  • 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.
{
"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)

Anchor link to

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

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

Windows (windows)

Anchor link to

Windows uses a different shape:

{
"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)

Anchor link to
  • body (string): message text.
  • content_variables (string): JSON-stringified variables for the bot-side template.
{
"telegram": {
"body": "Hello from Pushwoosh",
"content_variables": "{\"name\":\"John\"}"
}
}

Kakao (kakao)

Anchor link to
  • content (string): message content.
  • template (string): approved template code.
  • content_variables (string): JSON-stringified template variable bindings.
{
"kakao": {
"content": "Hello from Pushwoosh",
"template": "welcome_v1",
"content_variables": "{\"name\":\"John\"}"
}
}

LINE (line)

Anchor link to
  • 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.

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

Viber (viber)

Anchor link to

A Viber message is a free-text body, optionally with an image and a button or with a carousel, 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, unless image is set. Required with a button or a carousel.
  • image (string): public image URL. Ignored when template_id is set.
  • button_caption (string): button text, up to 30 characters. Set together with button_action. Requires body. Ignored when template_id is set.
  • button_action (string): button link: an http:// or https:// URL, a viber:// deep link, or an Omni token such as {lp-100} (a tracking-link placeholder that Omni Messaging resolves at send time). Set together with button_caption.
  • carousel (object): 2–5 swipeable cards shown under body. Can’t be combined with image, button_caption, button_action, or template_id. See Carousel.
  • 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<string, string>): 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, image, 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:

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

Transactional template:

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

carousel.items holds 2 to 5 cards. To set up a carousel in a journey instead, see Send a carousel. Each card has these fields:

  • title (string): card title, 2–38 characters. Required.
  • image (string): public http:// or https:// image URL. Required.
  • primary_button (object): main button. Required.
  • secondary_button (object): second button. Optional.

Each button has two fields, and both are required when the button is present:

  • caption (string): button text, up to 10 characters for primary_button and up to 12 for secondary_button.
  • action (string): button link: a URL with a scheme (http://, https://, viber://) or an Omni token such as {lp-100}, the same values as button_action.

A request that breaks any of these rules is rejected with INVALID_ARGUMENT. The google.rpc.BadRequest detail names the field, for example viber.carousel.items[0].title.

Example:

{
"viber": {
"body": "New arrivals are in. Swipe to see them.",
"carousel": {
"items": [
{
"title": "Running shoes",
"image": "https://example.com/img/shoes.jpg",
"primary_button": { "caption": "Buy now", "action": "https://example.com/shoes" },
"secondary_button": { "caption": "Details", "action": "{lp-100}" }
},
{
"title": "Sports backpack",
"image": "https://example.com/img/backpack.jpg",
"primary_button": { "caption": "Buy now", "action": "https://example.com/backpack" }
}
]
}
}
}

WhatsApp (whatsapp)

Anchor link to

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.

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

Facebook Messenger (fb_messenger)

Anchor link to

Facebook Messenger messages go through Meta and are subject to Meta’s messaging rules: free-form content is only delivered inside the 24-hour customer service window opened by an inbound message from the user. Outside that window, set message_tag to one of Meta’s approved use cases, or Meta rejects the send.

  • body (string): plain text message. Facebook Messenger has no template or button support, so this is the only content field.
  • message_tag (string): required outside the 24-hour window. One of CONFIRMED_EVENT_UPDATE, POST_PURCHASE_UPDATE, ACCOUNT_UPDATE, HUMAN_AGENT.
{
"fb_messenger": {
"body": "Hello from Pushwoosh",
"message_tag": "ACCOUNT_UPDATE"
}
}

For this channel there’s no separate device identifier: hwid, push_token, and user_id all resolve to the same value, the recipient’s Meta Page-Scoped ID (PSID). Target a specific conversation with any one of them in NotifyTransactional.

Terminal window
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": ["FB_MESSENGER"],
"hwids": { "list": ["<recipient-psid>"] },
"payload": {
"content": {
"localized_content": {
"default": {
"fb_messenger": { "body": "Hello from Pushwoosh" }
}
}
}
},
"schedule": { "at": "2026-05-01T12:00:00Z" }
}
}'

SMS has its own platform block inside each locale’s Content, 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 to the code (format XXXXX-XXXXX) of a saved SMS preset. 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.
{
"payload": {
"sms_preset": "XXXXX-XXXXX",
"content": {
"localized_content": {
"default": { "sms": { "body": "Your order has shipped." } },
"es": { "sms": { "body": "Tu pedido ha sido enviado." } }
}
}
}
}

Adding subject and file_urls to an sms block turns the message into an MMS. Only AbleMobile has an MMS endpoint — other SMS providers ignore both fields and deliver the plain-text body only.

  • subject (string): MMS subject. Requires at least one entry in file_urls — a subject without attachments is rejected. Up to 40 ASCII characters, or 13 characters if the subject contains non-ASCII characters.
  • file_urls (array of string): up to 3 attachment URLs. Each must be an absolute https URL ending in .jpg or .gif — .jpeg and .png are rejected by validation, even for a genuine JPEG or PNG file, because the provider can’t decode them. Each file must also be 200 KB or smaller; AbleMobile rejects the whole send if any attachment is heavier.
  • message_at (int): index into file_urls (0-based) that the SMS body text is shown after.

subject and file_urls support Liquid personalization, same as body.

{
"sms": {
"body": "Your order has shipped.",
"subject": "Order update",
"file_urls": [
"https://cdn.example.com/shipping-label.jpg",
"https://cdn.example.com/tracking-map.gif"
],
"message_at": 1
}
}

Adding rcs to an sms block sends a Twilio content template over RCS (Rich Communication Services) instead of body. Twilio delivers the template as an RCS message and falls back to an SMS built from the template’s twilio/text type, not from body. A template without a twilio/text type reaches RCS-capable phones only.

  • rcs.content_sid (string): SID of the Twilio content template, HX followed by 32 hex characters. Get it from ListRcsTemplates or the Twilio Console.
  • rcs.content_variables (string): JSON object of template variables, serialized as a string, for example "{\"1\": \"{FirstName|CapitalizeFirst|there}\"}". Values support tags and Liquid personalization. A variable you leave out takes the template’s default value.

body is still required in an sms block with rcs.

The request is rejected unless the application sends SMS through Twilio with its own Account SID, Auth token, and Messaging Service SID set in the SMS platform configuration. An application on Twilio credentials provided by Pushwoosh can’t send RCS.

An SMS preset can carry a template per locale. With sms_preset in the payload, the preset’s template is used for every locale where the request doesn’t bring its own rcs.content_sid.

{
"sms": {
"body": "Your order has shipped.",
"rcs": {
"content_sid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
"content_variables": "{\"1\": \"{FirstName|CapitalizeFirst|there}\", \"2\": \"A-1042\"}"
}
}
}

List RCS templates

Anchor link to

ListRcsTemplates returns the application’s Twilio content templates that can be sent over RCS, read with the application’s own Twilio credentials.

GET https://rpc-api.svc-nue.pushwoosh.com/api/sms_presets:rcs_templates?application=XXXXX-XXXXX
Authorization: Api YOUR_API_TOKEN
  • application (string, query): application code, format XXXXX-XXXXX.

The response holds a templates array. Only templates with at least one RCS content type are listed: twilio/card, twilio/carousel, twilio/quick-reply, twilio/call-to-action, or twilio/media.

FieldTypeDescription
content_sidstringTemplate SID, the value for rcs.content_sid.
friendly_namestringTemplate name in Twilio.
languagestringTemplate language code.
typesarray of stringTwilio content types the template defines, for example twilio/card and twilio/text.
variablesobjectTemplate variables with their default values.
has_sms_fallbackbooleantrue when the template has a twilio/text type, the SMS a phone without RCS receives.
{
"templates": [
{
"content_sid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
"friendly_name": "order_shipped_card",
"language": "en",
"types": ["twilio/card", "twilio/text"],
"variables": { "1": "there", "2": "your order" },
"has_sms_fallback": true
}
]
}

ListRcsTemplates returns these errors:

HTTP statusCause
400 Bad RequestThe application has no Twilio Account SID and Auth token of its own (FailedPrecondition).
401 UnauthorizedTwilio rejected the application’s credentials (Unauthenticated).
503 Service UnavailableThe Twilio Content API returned another error (Unavailable).

OpenAction

Anchor link to

Defines the action performed when the user opens the message.

Exactly one of:

  • rich_media (RichMedia): open a Rich Media page.
  • deep_link: open a deep link: { "code": "flow-code", "params": { "key": "value" } }.
  • link (Link): open a URL.
{
"open_action": {
"deep_link": { "code": "flow-code", "params": { "promo": "summer" } }
}
}

The deeplink URL and params values support Liquid personalization syntax — expressions are resolved before the deep link is opened.

{ "code": "XXXXX-XXXXX" } // by Rich Media code
{ "url": "https://..." } // by remote URL
{
"url": "https://example.com/promo",
"shortener": "BITLY"
}

shortener is NONE (default) or BITLY.

Configures how the message appears in Message Inbox.

{
"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.
  • expires_in (duration, e.g. "604800s"): how long the entry stays in the inbox, counted from the send date (the scheduled send_date, or the moment of the request for immediate sends). Must be positive. Ignored when expiration_date is set.

To set a relative lifetime instead of a fixed date, send expires_in alone:

{
"image_url": "https://cdn.example.com/inbox.png",
"expires_in": "604800s"
}

If your account has a maximum inbox lifetime, an expiration_date or expires_in beyond it is rejected.

NotificationPriority enum

Anchor link to

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

Example: Send a push to a segment

Anchor link to
Terminal window
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

Anchor link to
Terminal window
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"
}
}'