Documentation Index
Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Back-in-stock alerts let you recapture lost sales when a product goes out of stock. A “Notify me when available” button on your product page lets users opt in, and OneSignal sends the restock alert the moment the item is available again. The same flow works for push, email, or SMS — you choose the channel when you create the message template. This guide covers two approaches. Pick the one that matches how you store back-in-stock requests today:- Tag-based — Use this when OneSignal is the only system that needs to know who opted in. Each user-SKU pair is recorded as a tag, and a single Create Message API call fans out the restock alert to everyone tagged for that SKU.
- Custom Events with Journey — Use this when you already store
(user, SKU)records on your own backend. The opt-in fires a Custom Event that enters a single Journey; the Journey waits for a matching restock event and sends the alert. This trades a heavier customer-side build for native deduplication, no per-user tag limits, and Journey-level controls (expiration, frequency caps, channel sequencing).
Choose your approach
| Tag-based | Custom Events with Journey | |
|---|---|---|
| Where opt-ins live | OneSignal (as user tags) | Your backend |
| Per-restock work | One POST /notifications call with a tag filter | Backend iterates (user, SKU) records and fires one Custom Event per opted-in user |
| Cleanup after send | Required: segment → CSV export → blank → re-import | None — user exits the Journey naturally after the message step |
| Per-user opt-in limit | Plan-dependent — heavy opt-in users can hit per-user tag limits | Not a concern |
| Dedup across restocks | Manual via cleanup workflow | Native — Wait Until + Event Matching ensures one send per (user, SKU) instance |
| Multi-step nurture | Requires another tool (no built-in delays, channel sequencing) | Built into the Journey (delays, channel branches, control groups, A/B) |
| Customer build cost | Low (opt-in tag + one send call) | Higher (database + opt-in event + per-user fan-out) |
Prerequisites
Before you start, make sure you have:- Subscribers opted in to the channel you plan to use (push permission, email subscription, or SMS opt-in)
- Access to your app’s codebase or backend to record opt-ins when a user taps “Notify me”
- A signal from your inventory or commerce system (such as a webhook or scheduled job) that fires when a SKU returns to stock
- For the Custom Events approach: a
(user, SKU)table on your backend so you can fire one restock event per opted-in user
Approach 1: Tag-based
Each user gets one tag per SKU they opt in to:bis_requested_<SKU> = "1". When the SKU restocks, you call the Create Message API with a filter on that tag and OneSignal fans out the alert.
Set up your tag structure
For this flow, each user gets one tag per SKU they opt in to. The tag key encodes the SKU; the value is a sentinel.| Tag key | Example value | What it does |
|---|---|---|
bis_requested_<SKU> | "1" | Existence on a user signals that user has opted in for that SKU. The product name, image, and cart link are passed in custom_data at send time, so they don’t need to be stored on the user. |
Use the SKU verbatim from your backend. Tag keys via the SDK and API accept spaces, uppercase letters, and most punctuation, so
bis_requested_SKU 123 works as a tag key just as well as bis_requested_SKU_1234. Tag keys are case-sensitive, so pull the SKU from a single source (such as your product database) and use the exact same value at opt-in and at send time, or your filter will miss users.Tag the user when they tap “Notify me”
When a user taps your “Notify me when available” button, setbis_requested_<SKU> on that user. You can do this from your app via the OneSignal SDK, or from your backend via the REST API.
- SDK (Recommended)
- REST API
Call the OneSignal SDK from your app when the user taps the button. This is the most direct approach for mobile and web apps. The example below is JavaScript; the same
addTag call exists across platforms.| Reference | Description |
|---|---|
addTag method | Mobile SDK, Web SDK |
JavaScript
The tag is applied instantly. The user is now included in any audience filter that targets
bis_requested_SKU_1234.Create a message template
A template lets you define the message content once and reuse it across every restock send. You create it in the dashboard and reference it by ID in your API calls.- In your OneSignal dashboard, go to Templates and click New Template.
- Select the template type for the channel you want to send on — Push Notification, Email, or SMS.
-
Fill in the fields. The product name, image, and cart link are pulled from
custom_datayou pass at send time:Field Value Title {{message.custom_data.product_name}} is back in stock!Message {{message.custom_data.product_name}} is back! Grab it before it sells out.Image {{message.custom_data.image_url}}Launch URL {{message.custom_data.cart_url}} - Click Save Template and copy the Template ID. You will use it in the next step.
The same template handles every SKU because the product details come from
custom_data at send time, not from the user’s tags. You don’t need a separate template per product.Send the restock alert
When your inventory system detects that a SKU is back in stock, send the message to all users tagged withbis_requested_<SKU>.
- API (Recommended)
- Dashboard
Trigger the following Create message call from your backend when a SKU is restocked. OneSignal targets only users with the matching tag and personalizes the message using the Replace
custom_data you provide.YOUR_APP_ID with your OneSignal App ID, YOUR_TEMPLATE_ID with the Template ID you copied in the previous step, and YOUR_REST_API_KEY with your REST API key from Settings > Keys & IDs. Set target_channel to email or sms to send on those channels instead — the template_id must reference a template of the matching type.When the call succeeds, OneSignal delivers the message to every user tagged with
bis_requested_SKU_1234. The product name, image, and cart link are pulled from custom_data, so the same template renders correctly for any SKU.Clean up after sending
After a successful send, removebis_requested_<SKU> from the users who received the alert so they don’t get the same message twice on the next restock. Use OneSignal’s Bulk tag updates workflow — segment, export, blank, re-import:
Create a segment of opted-in users
Create a segment that filters users where
bis_requested_<SKU> exists. You can do this in Audience > Segments in the dashboard, or via the Create segments API.For SKU_1234, the segment is one filter: User Tag → bis_requested_SKU_1234 exists. Name it something predictable like BIS - SKU_1234 so you can find it for cleanup.Export the segment to CSV
Go to Audience > Subscriptions in the dashboard, filter by the segment, enable the External ID, Subscription ID, and Tags columns, and click Export. Or call the CSV export API with
segment_name set to the segment from the previous step.Blank the tag value in the CSV
Open the exported CSV and clear the value for
bis_requested_SKU_1234 on every row. Leave the identifier column (External ID or Subscription ID) and the other tag values intact.Approach 2: Custom Events with Journey
Each opt-in fires abis_requested Custom Event that enters a Journey. The Journey sends an immediate acknowledgment, then holds the user at a Wait Until step until your backend fires a matching bis_item_restocked event for that SKU. Event Matching on the Wait Until step ensures each Journey instance is paired to the right SKU, so a single Journey handles every product in your catalog.
This approach assumes you already store (user, SKU) records on your own backend so you can fan out the restock event when stock returns.
Send the opt-in event
When the user taps “Notify me when available,” fire abis_requested Custom Event with the SKU and item name as properties. Fire one event per SKU. If a user opts in to three SKUs, send three separate events — each one creates an independent Journey instance for that user.
- SDK (Recommended)
- REST API
Call the OneSignal SDK from your app when the user taps the button. The example below is JavaScript; the same
trackEvent call exists across platforms.| Reference | Description |
|---|---|
trackEvent method | Mobile SDK, Web SDK |
JavaScript
The event enters the user into the Journey instantly. If they opt in to another SKU, fire another
bis_requested event with the new SKU — they will run two parallel Journey instances.You can also fire
bis_requested from a third-party platform via Custom event sources (Segment, Amplitude, Mixpanel, BigQuery, and others). The Journey works the same regardless of source.Build the Journey
Create one Journey that handles every SKU. Wait Until’s Event Matching feature pairs each Journey instance to the correct restock event bysku.
Set the entry rule
In Messages > Journeys, create a new Journey. Set the entry rule to Custom Event and select
bis_requested.See Custom events entry rules for full details on Custom Event entry.Send an acknowledgment message
Add a message step right after entry to confirm the opt-in. Pick the channel that matches your alert (push, email, or SMS), create or select a template, and use Liquid to personalize with the entry event’s properties.Example message body:See Personalize with Custom Events for the full Liquid reference for
journey.first_event.Add a Wait Until step with Event Matching
Add a Wait Until action and set the condition to a custom event named
bis_item_restocked. Then enable Event Matching to pair the Journey instance to the right SKU:- Trigger Event Property:
sku— the property on the entrybis_requestedevent - Wait Event Property:
sku— the property on thebis_item_restockedevent
sku, only a bis_item_restocked event whose sku value matches the user’s original opt-in advances them through the step. See Event Matching for the canonical reference.Set an expiration branch so dormant instances don’t accumulate forever. A reasonable default is six months, with exit user as the expiration action — tune this to your restock cadence (shorter for fast-fashion, longer for evergreen catalog items).Send the restock message
Add a message step on the main branch of the Wait Until (the path users take when the event fires before expiration). Pick your channel and use Liquid to render the item name from the entry event:If you need fresh values from the restock event itself (for example, an updated price), reference them with
{{ journey.last_event.properties.<key> }} — journey.last_event resolves to the most recently stored event, which is the bis_item_restocked event after Wait Until advances.Trigger the restock event
When your inventory system detects that a SKU is back in stock, iterate the(user, SKU) records in your database and fire bis_item_restocked for each opted-in user. Each event must carry the sku so Event Matching pairs it to the correct Journey instance.
idempotency_key on each event if you implement retries — see Create custom events for the full schema.
When the events are processed, OneSignal advances the matching Journey instances through the Wait Until step and sends the restock message to each user. Instances that don’t match the
sku are unaffected.FAQ
Which approach should I use?
If OneSignal is your only system of record for back-in-stock requests, use the tag-based approach — it’s the lower-build option and lets a single API call fan out the alert. If you already store(user, SKU) records on your backend (for analytics, abandoned-cart, or other reasons), use Custom Events with Journey — you avoid per-user tag limits, get native dedup via Event Matching, and inherit the rest of Journey’s features (delays, channel branches, control groups). See Choose your approach for the full comparison.
Does OneSignal handle message throttling or frequency caps?
No. Any throttling — for example, frequency caps, batching, or how many restock alerts you send in a period — must be handled on your side (your app or backend). OneSignal does not apply those rules for you.Does OneSignal limit how many users can opt in to a back-in-stock alert?
No. OneSignal does not cap how many users can opt in for a SKU. When stock is limited, you should cap opt-ins yourself — for example, if a SKU only has 1,000 units, stop accepting new opt-ins (don’t set thebis_requested_<SKU> tag or fire bis_requested) once 1,000 requests have been reached.
How many SKUs can a single user opt in to?
For the tag-based approach, this depends on your plan’s per-user tag limit. Once a user reaches the limit, furtheraddTag calls fail silently. Plan to remove the tag after the restock alert is delivered so a heavy opt-in user is not blocked from new alerts. See Tags for limits and best practices.
For the Custom Events approach, there is no per-user opt-in limit — each opt-in is a separate Journey instance, not a tag.
How do I prevent a user from receiving the same restock alert twice?
For the tag-based approach, remove thebis_requested_<SKU> tag after the alert is delivered using the segment, export, and re-import workflow. See Clean up after sending for the full procedure.
For the Custom Events approach, dedup is automatic — each Journey instance only sends once and exits. If bis_item_restocked fires multiple times for the same (user, SKU), only the first one (while the user is in the Wait Until step) advances the instance; subsequent events have no effect on that instance.
Next steps
Tags
Reference for setting, removing, and segmenting users with tags.
Custom Events
Send and use Custom Events for Journey entry, Wait Until, and personalization.
Journey actions
Reference for Wait Until, Event Matching, and other Journey actions.
Create message API
Full schema for the Create Message endpoint, including filters and
target_channel.Message personalization
Use Liquid to personalize messages with tags and
custom_data.Personalize with Custom Events
Liquid syntax for
journey.first_event and Custom Event properties in Journey messages.