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).
Payload
Anchor link topreset(string): push preset code (formatXXXXX-XXXXX) to apply to this message.sms_preset(string): code (formatXXXXX-XXXXX) of a saved SMS preset. Its per-locale text is resolved into each locale’ssms.body. An inlinesms.bodyfor 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 withsilent.silent(bool): send a silent (data-only) push to every platform. Mutually exclusive withcontent. To make only some platforms silent, setsilentinsidecontentfor iOS or Android instead.custom_data(object): free-form JSON forwarded to the client SDK as theuparameter.open_action(OpenAction): action triggered when the user opens the notification.open_actions(map<Platform,OpenAction>): per-platform override ofopen_action. Key is a numericPlatformenum 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 toMaps 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 toContent delivered to a device is picked in this order:
- Exact match on the device’s language.
- Key
"default". - Key
"en". - 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 |
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 |
fb_messenger | Facebook Messenger message |
sms | SMS message |
Common push fields
Anchor link toThese 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" }}iOS (ios)
Anchor link tosubtitle(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):UNNotificationCategoryidentifier for interactive actions.interruption_level(string):passive,active,time-sensitive, orcritical.collapse_id(string): APNs collapse identifier. Notifications with the samecollapse_idreplace 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 insidecontent, so it works together with it. To make every platform silent, use the top-levelsilentinstead, which replacescontent. 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 toicon(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 samecollapse_keyreplace 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 insidecontent, so it works together with it. To make every platform silent, use the top-levelsilentinstead, which replacescontent. Set it in any locale to apply it to every locale. Thebaidu_androidblock also acceptssilent, 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 toUses 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 toUses 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 toaction(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 toicon,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 toUses 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 toWindows uses a different shape:
{ "windows": { "type": "TOAST", "template": { "title": "Hello", "body": "Tap to view" }, "tag": "promo", "cache": true, "time_to_live": "3600s" }}typeisTILE,TOAST, orBADGE.template(structured) orraw({ "content": "<raw xml>" }) — exactly one.
Telegram (telegram)
Anchor link tobody(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 tocontent(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 tocontent(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 toA 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 whentemplate_idis not set, unlessimageis set. Required with a button or a carousel.image(string): public image URL. Ignored whentemplate_idis set.button_caption(string): button text, up to 30 characters. Set together withbutton_action. Requiresbody. Ignored whentemplate_idis set.button_action(string): button link: anhttp://orhttps://URL, aviber://deep link, or an Omni token such as{lp-100}(a tracking-link placeholder that Omni Messaging resolves at send time). Set together withbutton_caption.carousel(object): 2–5 swipeable cards shown underbody. Can’t be combined withimage,button_caption,button_action, ortemplate_id. See Carousel.template_id(string): id of a pre-approved transactional template. When set, it takes precedence overbody.template_lang(string): template locale. Required whentemplate_idis 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;truedelivers 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
Anchor link tocarousel.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): publichttp://orhttps://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 forprimary_buttonand up to 12 forsecondary_button.action(string): button link: a URL with a scheme (http://,https://,viber://) or an Omni token such as{lp-100}, the same values asbutton_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 toWhatsApp 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 withcontent_id. This is independent of the outerLocalizedContentkey. The outer key selects content for a device, andlanguageselects 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 toFacebook 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 ofCONFIRMED_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.
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 (sms)
Anchor link toSMS 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 thesmsblock is present.
There are two ways to supply the text:
- Inline — set
sms.bodyper locale inlocalized_content. - From a preset — set the payload-level
sms_presetto the code (formatXXXXX-XXXXX) of a saved SMS preset. Its per-locale content is resolved intosms.bodyfor each locale the preset defines. An inlinesms.bodyfor 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 infile_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 absolutehttpsURL ending in.jpgor.gif—.jpegand.pngare 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 intofile_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,HXfollowed by 32 hex characters. Get it fromListRcsTemplatesor 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 toListRcsTemplates 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-XXXXXAuthorization: Api YOUR_API_TOKENapplication(string, query): application code, formatXXXXX-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.
| Field | Type | Description |
|---|---|---|
content_sid | string | Template SID, the value for rcs.content_sid. |
friendly_name | string | Template name in Twilio. |
language | string | Template language code. |
types | array of string | Twilio content types the template defines, for example twilio/card and twilio/text. |
variables | object | Template variables with their default values. |
has_sms_fallback | boolean | true 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 status | Cause |
|---|---|
400 Bad Request | The application has no Twilio Account SID and Auth token of its own (FailedPrecondition). |
401 Unauthorized | Twilio rejected the application’s credentials (Unauthenticated). |
503 Service Unavailable | The Twilio Content API returned another error (Unavailable). |
OpenAction
Anchor link toDefines 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.
RichMedia
Anchor link to{ "code": "XXXXX-XXXXX" } // by Rich Media code{ "url": "https://..." } // by remote URLLink
Anchor link to{ "url": "https://example.com/promo", "shortener": "BITLY"}shortener is NONE (default) or BITLY.
Inbox
Anchor link toConfigures 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 scheduledsend_date, or the moment of the request for immediate sends). Must be positive. Ignored whenexpiration_dateis 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 toControls notification priority on the target device, from PRIORITY_MIN (lowest) to PRIORITY_MAX (highest).
PRIORITY_UNSPECIFIEDPRIORITY_MINPRIORITY_LOWPRIORITY_DEFAULTPRIORITY_HIGHPRIORITY_MAX
Example: Send a push to a segment
Anchor link tocurl -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 tocurl -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" } }'