Unifies sending messages across push, email, and SMS

How to send a message

This guide will help you use the API effectively and assumes you've integrated our SDK into an Android, iOS, or Web app. If you do not intend to implement push in your messaging strategy, skip to next steps.

Craft a message

We'll send the message 'Hello, world' localized for Spanish, French, and Chinese.

// Message request body
{
  "contents": {
    "en": "Hello, world",
    "es": "Hola Mundo",
    "fr": "Bonjour le monde",
    "zh-Hans": "你好世界"
  }
}

Choose a targeting strategy

Choose only one strategy for targeting users with this message:

  • Segments
  • Filters
  • Aliases

We'll target the "Subscribed Users" segment so we send to everyone.

// Message request body
{
  "contents": {
    "en": "Hello, world",
    "es": "Hola mundo",
    "fr": "Bonjour le monde",
    "zh-Hans": "你好世界"
  },
  "included_segments": ["Subscribed Users"]
}

Pick the delivery channel

Messages can be delivered across the following channels:

  • Mobile and Web Push Notifications ("push")
  • Email ("email")
  • SMS ("sms")

Let's set our target_channel as Push Notifications.

{
  "contents": {
    "en": "Hello, World",
    "es": "Hola Mundo",
    "fr": "Bonjour le monde",
    "zh-Hans": "你好世界"
  },
  "included_segments": ["Subscribed Users"],
  "target_channel": "push"
}

Each channel has channel-specific parameters that can be included in the request body. You can access the channel parameters page by clicking on any of the Read more... links inside each API doc's parameter descriptions.

Set the delivery schedule

You can specify rate limits and delivery timing as well. See Delivery Notification Parameters to learn more.

Submit the request

The final cURL request will send the message to All Subscribers in each recipient's local language.

curl -X "POST" "https://api.onesignal.com/notifications" \
     -H 'Content-Type: application/json' \
     -H 'Authorization: Basic MjAyYzJlOTAtMTY4Mi00ODFlLTg2MDYtZTM2YzllM2ZlZTVi' \
     -d $'{
  "target_channel": "push",
  "included_segments": [
    "Subscribed Users"
  ],
  "app_id": "202d4f61-1ca9-42df-9d36-bb17d8123abc",
  "contents": {
    "en": "Hello, world",
    "es": "Hola mundo",
    "fr": "Bonjour le monde",
    "zh-Hans": "你好世界"
  }
}'

Next steps

Head to the API doc for the channel you'd like to use.


General notification parameters

name

Type string

Description

Serves as an internal identifier to help organize your notification campaigns. The name is not visible to the end-users and is used solely for your purposes within your campaign management workflow.

Assign meaningful names that reflect your notification campaign's purpose, content, or target audience to facilitate easier tracking and management of multiple campaigns.

custom_data

Type object

Description

User-specific or context-specific information for Message Personalization.

  • The object must be in JSON format.
  • The payload may include up to 2,048 bytes for Push and SMS notifications and up to 10 kilobytes for email messages.

Example

{
  "custom_data": {
    "cart_items": [
      {
        "item_name": "sweater",
        "img_url": "https://store.onesignal.com/assets/sweater.png"
      },
      {
        "item_name": "socks",
        "img_url": "https://store.onesignal.com/assets/socks.png"
      }
    ]
  }
}

idempotency_key

Type string

Description

Acts as a correlation identifier and an idempotency key to prevent duplicate notification deliveries. Idempotent Notification Requests enable you to send requests while ensuring users receive a message only once. Messages with the same idempotency_key send only one notification, and subsequent responses return the same result.

  • Keys must be unique. We recommend using a universally unique identifier (UUID) for this.
  • The key remains idempotent for 30 days, meaning any request with the same idempotency_key will not result in additional messages sent within this period. After 30 days, a notification with the same idempotency_key may be considered a new request and could result in a new message being sent.
  • This property used to be called external_id but has been updated to idempotency_key to reduce confusion with our User alias. Both will work in this case.

Example

{
  "idempotency_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Targeting

included_segments

Type string[]

Description

The segments to target for sending the message to. Members of each segment will receive the notification unless they're also members of a segment specified in the optional excluded segments parameter.

Provide an array of the Segment names.

Example

{
  "included_segments": [
    "Active Users",
    "Inactive Users"
  ]
}

excluded_segments

Type string[]

Description

Segments to exclude from receiving the message. Overrides membership in any segment specified in the included_segments parameter.

Provide an array of the Segment names.

Example

Target a message for customers who've spent $5K or more while excluding those deemed inactive, even if they are included in the segment "CLTV 5K".

{
  "included_segments": [
    "CLTV 5K"
  ],
  "excluded_segments": [
    "Inactive Users"
  ]
}

filters

Type object[]

Description

Filters allow you to dynamically define your notification's recipients based on their attributes or behaviors. They can be combined for complex targeting logic, enabling precise audience segmentation without the need to pre-define a segment. To learn more about the types of Filters that exist, refer to our documentation on Segments

Filter fields

The filters parameter targets notification recipients using an array of JSON objects containing field conditions to check. The following are filter field options:

fieldDescription
last_sessionrelation = ">" or "<"
hours_ago = number of hours before or after the user's last session. Example: "1.1"
first_sessionrelation = ">" or "<"
hours_ago = number of hours before or after the user's first session. Example: "1.1"
session_countrelation = ">", "<", "=" or "!="
value = number sessions. Example: "1"
session_timerelation = ">" or "<"
value = Time in seconds the user has been in your app. Example: "3600"
amount_spentrelation = ">", "<", or "="
value = Amount in USD a user has spent on IAP (In App Purchases). Example: "0.99"
bought_skurelation = ">", "<" or "="
key = SKU purchased in your app as an IAP (In App Purchases). Example: "com.domain.100coinpack"
value = value of SKU to compare to. Example: "0.99"
tagrelation = ">", "<", "=", "!=", "exists", "not_exists", "time_elapsed_gt" (paid plan only) or "time_elapsed_lt" (paid plan only)
See Time Operators

key = Tag key to compare.
value = Tag value to compare. Not required for "exists" or "not_exists". Example: See Formatting Filters

Do not use tags for targeting individual users via a "user id". Instead use external_id or custom alias and the include_aliases targeting property.
languagerelation = "=" or "!="
value = 2 character language code. Example: "en". For a list of all language codes see Language & Localization.
app_versionrelation = ">", "<", "=" or "!="
value = app version. Example: "1.0.0"
locationradius = in meters
lat = latitude
long = longitude
countryrelation = "="
value = 2-digit Country code
Example: "field": "country", "relation": "=", "value": "US"

Using Filters

  • Filter entries use "AND" by default; insert {"operator": "OR"} between entries to "OR" the parameters together.
  • "AND" has priority over "OR".
  • For performance reasons, a maximum of 200 entries can be used at a time. The 200 entries limit includes the "field" entry and "OR" entries -- each would count towards the 200 limit. Below, "Formatting Example 1" would be 2 entries and "Formatting Example 2" would be 3 entries.
  • Tag filters using an equality ("=") or "exists" operator are very fast.
  • Negation (eg. "!=" and "not_exists") is inherently more expensive to compute. Our default database indices map tags to devices, and can’t track which devices don’t have specific tags -- there are infinite tag keys which each device does not have. Upon request, it is sometimes possible for us to create a specific index on your application to address problems with negation.
  • Numeric ordering operators like "<" or ">" are slow by default. Note that upon special request, we can add a special index for specific tags to improve performance of these operators.
  • Filters on the "last_session", "session_count", and "country" fields are fast on their own or together, but when used with other filters such as tags can make the segment take longer to compute.

Formatting Filters

The power of filters comes from combining several fields and operators to precisely target your users. The following are examples of filters and how to format them:

  1. A user is level 10 and purchased an item

  2. A user is level 10 or 20

  3. A user is not VIP or is admin

  4. User's tags include key username and the user is not banned.

"filters": [
  {"field": "tag", "key": "level", "relation": "=", "value": "10"},
  {"field": "amount_spent", "relation": ">","value": "0"}
]
"filters": [
  {"field": "tag", "key": "level", "relation": "=", "value": "10"}, 
  {"operator": "OR"}, {"field": "tag", "key": "level", "relation": "=", "value": "20"}
]
"filters": [
  {"field": "tag", "key": "is_vip", "relation": "!=", "value": "true"},
  {"operator": "OR"}, {"field": "tag","key": "is_admin", "relation": "=", "value": "true"}
]
"filters": [
  {"field": "tag", "key": "username", "relation": "exists"},
  {"field": "tag", "key": "banned", "relation": "!=", "value": "true"}
]

include_aliases

Type object

Description

Targets specific users based on their Aliases & External ID.

  • Provide an object of aliases to include.
    • User's External ID – external_id
    • OneSignal ID – onesignal_id
    • Custom alias name – some_custom_alias
  • You may include up to 2,000 Alias IDs per API call.

Example

Send a message to the users identified by the EUIDs "one", "two", and "three" using the push channel.

{
  "include_aliases": {
    "external_id": [
      "one",
      "two",
      "three"
    ]
  }
}

💡

Use with the target_channel parameter to control the delivery channel.

include_subscription_ids

Type string[]

Description

Allows targeting users based on their Subscription ID.

You may include up to 2,000 IDs per API call.

Example

{
  "include_subscription_ids": [
    "1dd608f2-c6a1-11e3-851d-000c2940e62c"
  ]
}

target_channel

Type string

Description

The channel in which to deliver a message. Use in conjunction with include_aliases.

Choose from the following options:

  • "push" – send the message as a push notification
  • "email" - send the message as an email
  • "sms" - send the message as a text message

Example

{
  "target_channel": "push"
}

Delivery

send_after

Type string

Description

Schedule notifications for future delivery; defaults to Coordinated Universal Time (UTC). Align delivery with your target users' time zones so they're more likely to see it.

Specify the string according to the ISO 8601 calendar format. A heuristic you can use to determine whether we can parse your date-time string is whether Javascript's Date constructor can parse the string.

Example

All of the following are valid and equivalent formats for the same date and time:

  • { "send_after": "Thu Sep 24 2015 14:00:00 GMT-0700 (PDT)" }
  • { "send_after": "2015-09-24 14:00:00 GMT-0700" }
  • { "send_after": "Sept 24 2015 14:00:00 GMT-0700" }

delayed_option

Type string

Description

Choose how deliveries should be scheduled. Not compatible with Push Throttling, set throttle_rate_per_minute to 0 to disable throttling if enabled.

  • timezone – simultaneous across time zones at the same local time.
  • last-active – enable Intelligent Delivery, which schedules notifications based on the user's Last Active Session.

Example

Deliver the notification worldwide at 9 AM in each user's local time zone.

{
  "delayed_option": "timezone",
  "send_after": "2024-03-05T15:00:00.600Z"
}

delivery_time_of_day

Type string

Description

Specify when the message should be delivered when the delayed_option parameter is "timezone". It's ideal for time-sensitive daily digests, reminders, or promotions.

  • Format the time as a string, which can be in various formats such as:
    • 12-hour e.g., "9:00AM"
    • 24-hour e.g., "21:45"
    • HH:mm:ss format - e.g., "9:45:30"

Example

Schedule a notification for all users in the morning at 9:00 AM local time.

{
  "delayed_option": "timezone",
  "delivery_time_of_day": "9:00AM"
}

Path

notification_id

The identifier of the message of interest. Locating this value depends on how the message was created.

Outcomes

Parameters for View Outcomes can be used with this View Notification API.

Search

app_id

Type string

Description

Identifies your application within our system.

  • The value must be a universally unique identifier (UUID).
  • Refer to Keys & IDs to learn more.

limit

Type number

Description

Specifies the maximum number of notifications to return in a single query.

This parameter helps control the volume of data retrieved during one operation, especially when navigating many notifications.

  • The default value is 50.
  • The maximum value that can be used is 50.

offset

Type number

Description

Controls the starting point for the notifications being returned.

Results are returned and sorted in descending order by queued_at.

  • The default value is 0 (Starts at the beginning of your notification list).

kind

Type number

Description

Specifies the type of notifications to return.

Use this to segment notifications by their creation method, allowing for targeted analysis or management of notification types.

  • All notification types are returned by default.
  • 0 — Notifications created through the dashboard.
  • 1 — Notifications sent via API calls.
  • 3 — Notifications triggered through automated systems.

template_id

Type string

Description

Specifies the identifier of a pre-defined template used to configure a message.

To obtain the template_id, navigate to the relevant template in your dashboard. It's typically found in the URL or designated section within the template settings.