Set up web push

New

Generate your workspace's web push keys, add the Customer.io service worker and web push plugin to your website, and ask visitors for permission to send them notifications.

Contact us to turn on web push

Web push is in alpha. If you don’t see a Web tab under Settings > Push, contact us to turn it on for your account. This link opens your most recently used workspace; check the workspace name before you generate keys.

Before you begin

  • Add our JavaScript source to your website and connect it to the workspace you’ll send web push from. The web push plugin works with the source you already have; you don’t add a second snippet.
  • Turn on the device actions on the source’s Journeys destination. In Data & Integrations > Sources, open your JavaScript source and check its Customer.io Journeys destination. Create or Update Device must be on, or browser subscriptions never become devices on people’s profiles. Turn on Delete Device too, so a browser is removed from the person’s profile when they sign out or turn notifications off on your site. A “Journeys Workspace” destination that Customer.io creates with the source has both on; a Journeys destination you add by hand, or create through the API without enabling its actions, has them off. See the Customer.io destination’s actions.
  • Serve your website over HTTPS. Browsers only allow web push on secure sites. You can use http://localhost while you develop. But the service worker only opens https:// links, so on http://localhost a notification opens your site’s root even when Link is a path like /bookings/123. Test links on an HTTPS site.
  • Identify people when they sign in. Customer.io adds a browser to a person’s profile only after you identify them, so you can only offer notifications to signed-in visitors.
  • Choose one website. During the alpha, web push supports one website per workspace. A web push action can’t target a website yet, so if you set up web push on a second website, people who subscribed on either site get every notification. Support for more than one website is coming.

1. Generate your web push keys

Your workspace has one key pair for web push. Browsers use the public key to subscribe, and Customer.io uses the private key to sign each notification. You don’t need an account with Apple, Google, or another push provider.

  1. Go to Settings > Push > Web.
  2. In VAPID subject, enter a contact address for your company, like mailto:push@yourbrand.com or https://yourbrand.com/contact, using your own public domain. Push services use it to contact you if there’s a problem with your notifications. The field starts with your own email address; replace it with your company’s address.
  3. Click Generate and save keys. Customer.io creates the key pair and saves it with your subject right away, so there’s nothing else to save. The page shows Keys saved with the date.
  4. Click Copy public key. You’ll add it to your website in step 3.
The Web tab under Settings > Push, with a VAPID subject, a public key, and the Copy public key button

The subject must be a mailto: address or an https:// URL on a real, public domain that you control. Customer.io doesn’t save a subject on a test or local domain, like .test, .local, or localhost, or on an IP address, because Apple’s push service rejects them. If your workspace saved such a subject before Customer.io checked domains, Settings > Push > Web shows a warning: Customer.io leaves the subject out of notifications to Safari, so they still arrive, and sends it as saved to other browsers. Update it to an address on your public domain. The subject is your company’s contact address; it isn’t your website’s address or a subscriber’s email, so use a public address even when you test on localhost.

Don't regenerate your keys after you go live

Each browser subscription only works with the public key it subscribed with. If you click Regenerate keys…, Customer.io asks you to confirm, then saves a new key pair as soon as you click Regenerate and save. From then on, every existing subscriber stops receiving web push. The plugin subscribes with the vapidPublicKey your website gives it, so subscribers can only recover after you update your website to the new public key. Then each existing subscriber needs to visit your site and subscribe again. Only regenerate your keys if your private key might have leaked, or you’re starting over. Disable… deletes your keys, which has the same effect on your subscribers.

To change your contact address, edit VAPID subject and click Save changes; you don’t need new keys. Until you save, the page reminds you that your subject change isn’t saved; your keys are already saved.

If you try to generate or regenerate keys after someone changed them in another tab or browser, Customer.io doesn’t replace the newer keys. The page says that your web push keys changed since the page loaded; click Reload to see the current keys before you do anything else.

Your public key isn’t a secret, so you can put it in your website’s code. Customer.io never shows your private key.

2. Add the service worker to your website

A service worker is a JavaScript file that the browser runs in the background. The Customer.io service worker shows each notification, opens your link when someone clicks it, and reports delivered and opened metrics. Browsers only run a service worker that comes from your own domain, so you need to host a copy of the file on your website.

  1. Download cio-webpush-sw.js from https://cdp.customer.io/v1/analytics-js/cio-webpush-sw.js. If your account is in our EU region, use https://cdp-eu.customer.io/v1/analytics-js/cio-webpush-sw.js. If you install the SDK from npm, the same file is in node_modules/@customerio/cdp-analytics-browser/dist/cio-webpush-sw.js.
  2. Put the file in your website’s public root, so that it loads from https://your-site.com/cio-webpush-sw.js.
  3. Check that the URL returns the file as JavaScript over HTTPS, without a redirect.

You only need to host the file once. From version 0.8.0, your copy of cio-webpush-sw.js updates itself. When the browser installs the service worker, it also loads the latest service worker code from https://cdp.customer.io/v1/analytics-js/cio-webpush-sw-runtime.v1.js (https://cdp-eu.customer.io/v1/analytics-js/cio-webpush-sw-runtime.v1.js in the EU region). When that code is newer than the copy inside your file, the service worker uses it. Browsers check that URL for changes whenever they check your service worker for updates, so you get service worker fixes without copying the file again.

Your file also contains a complete copy of the service worker code. If the browser can’t load the code from our CDN, for example because an ad blocker, your Content Security Policy, or a network error blocks it, the service worker uses the copy in your file and keeps working. To control where the code comes from, see the runtimeUrl option.

Upgrading from version 0.7.1 or earlier

Copies of cio-webpush-sw.js from version 0.7.1 and earlier don’t update themselves. Download the file once more and replace your copy. If you install the SDK from npm, upgrade to version 0.8.0 or later first, then copy the file from node_modules again. After that, you don’t need to replace it again for updates.

Ad blockers

The default lists in ad blockers like uBlock Origin block cdp.customer.io on other websites. In those browsers, the service worker keeps working with the copy in your file, but it doesn’t update itself. The same lists also block the snippet that loads our JavaScript SDK and the web push plugin from cdp.customer.io, so visitors with an ad blocker can’t subscribe at all.

If notifications matter for visitors who use ad blockers, install the SDK from npm, which includes the plugin, and send every Customer.io request through a custom proxy on your own domain. Ad blocker lists block Customer.io’s hosts, including cdp.customer.io and track.customer.io. They also block any URL whose path contains /analytics-js/, even on your own domain, so map your proxy to paths without that segment, like /cio/:

  • Set cdnURL and the apiHost of the Customer.io Data Pipelines integration to your proxy, as described on the proxy page, so the SDK loads its settings and sends its API calls through your domain.
  • Set trackUrl to your proxy’s route to track.customer.io (or track-eu.customer.io), so delivered and opened metrics arrive.
  • Set runtimeUrl to the URL of a route on your proxy that serves https://cdp.customer.io/v1/analytics-js/cio-webpush-sw-runtime.v1.js (or the cdp-eu.customer.io URL), like https://<YOUR-PROXY-HOST>/cio/cio-webpush-sw-runtime.v1.js. Use the full URL, because the service worker resolves a path like /cio/cio-webpush-sw-runtime.v1.js against your website’s domain. A path only works when your proxy runs on that domain. A /cio/* rule that only removes the prefix doesn’t cover this file, because its path on our CDN contains /analytics-js/, so add a separate rewrite for it, as described in ad blockers on the proxy page.

A proxy doesn’t reliably get the snippet past these lists: depending on your settings, the snippet loads some of its files from a /v1/analytics-js/ path on the host that serves it, and you can’t change that path. The npm SDK does the same for device-mode destinations, so ad blockers still block those destinations behind a proxy.

If your site already has a service worker

Don’t replace your existing service worker. A page can only have one service worker for a given path, and the plugin won’t replace a different worker at the same path. Choose one of these approaches:

  • Import our worker into yours. Add these lines to the top of your existing service worker, and set serviceWorkerUrl to your worker’s path in step 3. Setting cioWebPushLifecycle to false keeps your worker in charge of its own updates. Our handlers ignore notifications that didn’t come from Customer.io, so they work alongside other push code.

    JAVASCRIPT
    self.cioWebPushLifecycle = false;
    importScripts('/cio-webpush-sw.js');

    The plugin registers your worker with a ?track= query that tells our code where to report metrics, and sometimes a ?runtime= query that tells it where to load its code. If your own code also registers the worker, copy the whole URL the plugin registered, including both queries, or you’ll lose delivered and opened metrics. If you import our file this way, your worker must keep calling skipWaiting() and clients.claim() itself, because setting cioWebPushLifecycle to false turns them off in our code. importScripts only works in a classic service worker. If your site uses a module service worker, leave it alone and serve our worker in its own scope instead, for example at /notifications/cio-webpush-sw.js; the plugin always registers its worker as a classic script, so bundling our code into a module worker doesn’t work.

  • Give our worker its own path. Put the file in a folder, like /notifications/cio-webpush-sw.js, and set serviceWorkerUrl to that path. Your existing worker keeps the rest of your site.

3. Add the web push plugin

The web push plugin adds a webPush object to your JavaScript source. Loading the plugin doesn’t ask for permission or register the service worker; that only happens when a visitor clicks your button in step 4.

Once your workspace has web push keys, the JavaScript source’s page also offers a snippet with your public key and region already filled in. Open the source, go to Installation instructions, switch to Copy and paste code, and find Add web push. Keep your JavaScript source snippet in the head section, and paste the whole Add web push block into the body where you want the button, with its <button> before its scripts. The block’s scripts look up the button when the SDK is ready, so they need the button on the page first. That snippet differs from the one below, which also adds a turn-off button and a status line. Use either one.

Add this after your existing JavaScript source snippet. Replace YOUR_PUBLIC_KEY with the key you copied in step 1. If your account is in our EU region, load the plugin from cdp-eu.customer.io and set trackUrl to https://track-eu.customer.io.

HTML
<script src="https://cdp.customer.io/v1/analytics-js/webPushPlugin.js"></script>
<script>
  cioanalytics.ready(async () => {
    // The plugin script was blocked or failed to load: leave your button disabled.
    if (!window.CustomerIOWebPush) {
      console.warn('Customer.io web push did not load, so notifications are unavailable on this page.');
      return;
    }
    await cioanalytics.register(CustomerIOWebPush.WebPushPlugin({
      vapidPublicKey: 'YOUR_PUBLIC_KEY',
      serviceWorkerUrl: '/cio-webpush-sw.js',
      trackUrl: 'https://track.customer.io'
    }));
  });
</script>

Ad blockers, a Content Security Policy, or a network error can stop webPushPlugin.js from loading. The check for window.CustomerIOWebPush keeps your page from throwing an error when that happens; tracking still works, and your button stays disabled.

Register the plugin after you load the SDK. Replace YOUR_PUBLIC_KEY with the key you copied in step 1. If your account is in our EU region, set cdnURL to https://cdp-eu.customer.io when you load the SDK, and set trackUrl to https://track-eu.customer.io.

JAVASCRIPT
import { AnalyticsBrowser, WebPushPlugin } from '@customerio/cdp-analytics-browser'

const [analytics] = await AnalyticsBrowser.load({
  writeKey: 'YOUR_WRITE_KEY',
  // cdnURL: 'https://cdp-eu.customer.io', // Set if you're in our EU region
})
await analytics.register(WebPushPlugin({
  vapidPublicKey: 'YOUR_PUBLIC_KEY',
  serviceWorkerUrl: '/cio-webpush-sw.js',
  trackUrl: 'https://track.customer.io',
}))
OptionDescription
vapidPublicKeyThe public key from Settings > Push > Web.
serviceWorkerUrlThe path to the service worker on your site. Defaults to /cio-webpush-sw.js. It must be on the same domain as your page.
trackUrlWhere the service worker reports delivered and opened metrics. Defaults to https://track.customer.io. Use https://track-eu.customer.io in the EU region.
runtimeUrlWhere the service worker loads its latest code. Defaults to https://cdp.customer.io/v1/analytics-js/cio-webpush-sw-runtime.v1.js, or the cdp-eu.customer.io URL when trackUrl is https://track-eu.customer.io. To serve the code from your own proxy, set it to the full URL of a route that serves our runtime file, like https://<YOUR-PROXY-HOST>/cio/cio-webpush-sw-runtime.v1.js (see ad blockers). The service worker resolves a path like /cio/cio-webpush-sw-runtime.v1.js against your website’s domain, so a path only works when your proxy runs on that domain. If you’re in our EU region and set trackUrl to your own proxy, set runtimeUrl too, or the service worker loads its code from the US CDN. Set it to false to stop the service worker from loading code from anywhere outside your file. With false, download a new copy of cio-webpush-sw.js yourself when release notes say the service worker changed.

The first time a browser subscribes, the plugin checks that the runtimeUrl host responds before it registers the service worker. If the request fails or the host doesn’t respond within 3 seconds, the plugin registers the service worker with the copy in your file, and the service worker in that browser doesn’t update itself later. To turn updates back on in those browsers, for example after you start serving the code from your own domain, set runtimeUrl explicitly. If the service worker hasn’t started within 30 seconds, subscribe() rejects with Web push service worker did not activate within 30 seconds. The browser can still finish installing it, so it’s safe to call subscribe() again.

If your site uses a Content Security Policy, it needs to allow the service worker and the plugin’s script host. See Content Security Policy for web push.

4. Ask for permission in a click

Browsers only show the permission prompt when someone clicks or taps something on your page. Add a button that explains what people get, like Turn on booking alerts, and call webPush.subscribe() when they click it.

subscribe() asks for permission, subscribes the browser, and adds a web device to the identified person’s profile. Identify the person when they sign in, before they can click the button.

This sample is one copy-and-paste script for the snippet install: it registers the plugin from step 3, with the same window.CustomerIOWebPush check, and then wires the buttons, all in one cioanalytics.ready callback. Use it in place of the step 3 script; don’t keep both. Replace YOUR_PUBLIC_KEY as you did in step 3. If your account is in our EU region, load the plugin from cdp-eu.customer.io and set trackUrl to https://track-eu.customer.io.

HTML
<button id="enable-alerts" disabled>Turn on booking alerts</button>
<button id="disable-alerts" disabled>Turn off alerts</button>
<p id="alert-status" aria-live="polite"></p>
<script src="https://cdp.customer.io/v1/analytics-js/webPushPlugin.js"></script>
<script>
  cioanalytics.ready(async () => {
    const enable = document.querySelector('#enable-alerts');
    const disable = document.querySelector('#disable-alerts');
    const status = document.querySelector('#alert-status');

    // The plugin script was blocked or failed to load: leave your buttons disabled.
    if (!window.CustomerIOWebPush) {
      console.warn('Customer.io web push did not load, so notifications are unavailable on this page.');
      return;
    }
    await cioanalytics.register(CustomerIOWebPush.WebPushPlugin({
      vapidPublicKey: 'YOUR_PUBLIC_KEY',
      serviceWorkerUrl: '/cio-webpush-sw.js',
      trackUrl: 'https://track.customer.io'
    }));

    // Identify the signed-in person before you offer alerts.
    await cioanalytics.identify(currentUser.id, { email: currentUser.email });

    async function refresh() {
      const on = Boolean(await cioanalytics.webPush.subscription());
      enable.disabled = on;
      disable.disabled = !on;
      status.textContent = on ? 'Booking alerts are on.' : 'Booking alerts are off.';
    }

    enable.onclick = () => {
      enable.disabled = true;
      // Call subscribe() first, with no await before it, so Safari shows the prompt.
      cioanalytics.webPush.subscribe().then(refresh).catch((error) => {
        enable.disabled = false;
        status.textContent = Notification.permission === 'denied'
          ? 'Notifications are blocked. Allow them in your browser settings, then try again.'
          : error.message;
      });
    };

    disable.onclick = () => cioanalytics.webPush.unsubscribe().then(refresh).catch((error) => {
      status.textContent = error.message;
    });

    await refresh();
  });
</script>

Replace currentUser with however your site stores the signed-in person.

Safari: call subscribe() directly in your click handler

Safari only shows the permission prompt if your code calls subscribe() right away when someone clicks. Don’t wait for anything first, like identify, a network request, a timer, or your own Notification.requestPermission() call. If you do, Safari refuses to subscribe, even after the person clicks Allow. It’s fine to handle the result of subscribe() afterward.

A few more things to build into your page:

  • Hide the button in browsers that can’t receive web push. Check for serviceWorker in navigator, PushManager in window, and Notification in window before you show it.
  • Show recovery steps when notifications are blocked. When Notification.permission is denied, the browser won’t ask again, and your page can’t change that. Tell people how to allow notifications in their browser, then ask them to click your button again. See troubleshooting.
  • Call cioanalytics.reset() when someone signs out. It removes the browser from that person’s profile, so the next person who signs in on the same browser doesn’t get their notifications. A browser follows the person last identified on it: if you don’t call reset() on sign-out, the device moves to the next person who signs in on that browser. Identify the next person before you offer alerts again.
  • Let people turn alerts off. webPush.unsubscribe() unsubscribes the browser and removes the device from the person’s profile.

For what the plugin and service worker collect, where consent comes from, and how to undo web push, see data, consent, and removal.

If someone subscribes before you identify them, the browser subscribes, but Customer.io doesn’t add the device until you call identify.

Device attributes

When the plugin adds a web device, it sets the device’s origin attribute to the website the browser subscribed on (the page’s location.origin, like https://www.yourbrand.com). Browsers that subscribed with an earlier version of the plugin get the attribute on their next identified visit to your site. Customer.io doesn’t use origin to choose who gets a notification yet; it records the website so that you can target websites when support for more than one website per workspace arrives. If you load the plugin with the snippet, it updates automatically from our CDN and records origin without any change on your side. If you install the SDK from npm, use version 0.7.0 or later to record origin.

Plugin methods

MethodReturnsDescription
webPush.subscribe()PromiseAsks for permission if needed, subscribes the browser, and adds a web device to the identified person. Rejects if the browser doesn’t support web push or the person doesn’t allow notifications.
webPush.subscription()PromiseThe browser’s current subscription, or null if it isn’t subscribed.
webPush.unsubscribe()PromiseUnsubscribes the browser and removes the web device from the person’s profile.
webPush.requestPermission()PromiseAsks for permission without subscribing. You don’t need it, because subscribe() asks for permission. Don’t call it before subscribe() in Safari.

iOS and iPadOS

On iPhone and iPad, web push only works in a web app that the person adds to their Home Screen. A normal Safari tab doesn’t have the notification APIs, so your button can’t work there.

To support iOS and iPadOS 16.4 and later:

  1. Add a web app manifest to your site, with display set to standalone or fullscreen. Serve it from your HTTPS domain, for example as /manifest.webmanifest:

    JSON
    {
      "id": "/",
      "name": "Your App",
      "short_name": "Your App",
      "start_url": "/",
      "scope": "/",
      "display": "standalone",
      "icons": [
        { "src": "/icons/app-192.png", "sizes": "192x192", "type": "image/png" },
        { "src": "/icons/app-512.png", "sizes": "512x512", "type": "image/png" }
      ]
    }
  2. Link the manifest and a Home Screen icon in the <head> of your pages:

    HTML
    <link rel="manifest" href="/manifest.webmanifest">
    <link rel="apple-touch-icon" href="/icons/apple-touch-icon-180.png">
  3. In a normal Safari tab, show instructions instead of your button: tap Share, then Add to Home Screen, then open your app from the Home Screen and sign in. You can tell that your page is running as a Home Screen app when window.matchMedia('(display-mode: standalone)').matches or navigator.standalone is true.

  4. In the Home Screen app, people tap your button to subscribe, just like on desktop.

Notifications on iOS and iPadOS use your Home Screen app’s icon and name.

5. Test your setup

A successful subscription doesn’t prove that notifications arrive. Test the whole path with your own browser before you send to your audience.

After you save your keys, Settings > Push > Web shows a Test web push section with two tests. Both send a notification titled TEST and report what happened. Settings tests check sending without creating a real automation delivery, so they don’t create an automation Sent tab entry or delivery metrics. To check those, send a real test delivery.

  1. Send a test to this browser to check your keys. You don’t need your website for this test.
  2. Sign in to your site as a test person and click your button. Allow notifications when the browser asks.
  3. In Customer.io, open the test person’s profile and go to Devices. You should see a web device. If you don’t, check that the source’s Journeys destination has Create or Update Device turned on. Its token is the browser’s push address, which starts with https://. Expand the device to see Site, the website the browser subscribed on, like https://www.yourbrand.com. The API stores this as attributes.origin.
  4. Send a test to a person: pick your test person to check that the browsers your site subscribed receive notifications.
  5. Send a real test delivery to check delivery history and metrics.

If nothing arrives, see troubleshooting.

Send a test to this browser

This test sends a notification to the browser you’re using Customer.io in, with your workspace’s keys. It checks your keys and Customer.io’s sending, but not your website: the notification comes from the Customer.io app (for example, fly.customer.io), not from your site. The test doesn’t add a device or a person to your workspace, and this browser doesn’t become one of your site’s subscribers.

  1. Under Send a test to this browser, click Test this browser.
  2. If you haven’t allowed notifications from the Customer.io app in this browser yet, your browser asks you to. Click Allow.
  3. The notification appears in this browser, and the card shows Sent and shown in this browser. If the card only says Sent, the browser’s push service accepted the test, but Customer.io couldn’t confirm that the browser showed it. Check that your computer’s notification settings allow your browser to show notifications, and that Focus or Do Not Disturb is off.

Click Send again to repeat the test. Click Forget this browser to remove this browser’s test subscription. Forgetting doesn’t change the browser’s notification permission; you can change that in your browser’s site settings.

If the test can’t send, the card tells you why:

What the card showsWhat to do
Notifications from the Customer.io app, like fly.customer.io, are blockedClick the icon to the left of the address bar, allow notifications, then click Try again. Blocking notifications for the Customer.io app blocks every Customer.io notification in that browser, not only tests.
Notifications weren’t allowedThe browser didn’t show the permission prompt, or you dismissed it. Click the icon to the left of the address bar to allow notifications, then click Try again.
This browser’s push service is turned offTurn on push messaging in your browser’s settings, then click Try again. Brave turns off push messaging by default: turn on Use Google services for push messaging in brave://settings/privacy, restart Brave, then try again.
This browser can’t receive web push from this pageUse send a test to a person, or open Customer.io in Chrome, Edge, Firefox, or Safari on a computer. Safari on iPhone and iPad only supports web push in web apps added to the Home Screen.

If the send itself fails, the card shows the same reasons as a test to a person, with the next step.

Send a test to a person

This test sends a notification to the browsers your site subscribed for one person, with your real setup, and shows what each browser’s push service said.

  1. Under Send a test to a person, search for the person by email or enter their exact ID. You can type the start of an email address, like maya, or paste the person’s id or cio_id. Only people with at least one subscribed browser are listed, and your workspace’s test people come first, marked Test person. If you leave the search empty, the list shows people who have a browser.
  2. Pick the person. Customer.io selects their first 10 browsers, or all of their browsers if they have fewer. Clear any you don’t want to test. One test reaches up to 10 browsers; to select another browser when 10 are selected, clear one first.
  3. Click Send test to n browsers.

The test ignores topic, frequency, and quiet-hours rules. The results show one row per browser. Sent means the browser’s push service accepted the notification; a browser that’s closed or offline can show it when it comes back, if the push service still holds it. When a browser doesn’t get the test, its row says why and what to do next:

ResultWhat it means and what to do
UnsubscribedThe browser isn’t subscribed anymore, or its subscription expired. The next real send removes it from the person’s profile. The person needs to allow notifications on your site again.
Subscribed with a different keyThe browser subscribed with an older public key, before your keys were regenerated. It stays on the person’s profile, and real sends to it fail until the person subscribes again on your site with your current public key.
Keys or subject rejectedThe push service refused your keys or your VAPID subject. Check your subject.
Subscription incompleteThe web device is missing information that Customer.io needs to send to it. It stays on the person’s profile, and real sends to it fail until the person subscribes again on your site.
Push service didn’t answerThe push service was busy or unavailable. Try again in a minute.
Timed outThe push service didn’t answer within 20 seconds. The notification might still arrive.
Couldn’t reach the push serviceCustomer.io couldn’t reach the browser’s push service. Try again.

A test never removes a browser from a person’s profile. Only a real send to an unsubscribed or expired browser removes it. If you send many tests in a short time, Customer.io asks you to wait a minute before you try again.

Advanced: test a subscription JSON

To test a browser that isn’t on a person’s profile yet, like an anonymous visitor’s browser or a browser on a site that doesn’t identify people yet, open Advanced: test a subscription JSON under the other tests and paste the browser’s subscription JSON. To get it, open your site in the browser you want to test, open your browser’s JavaScript console, and run:

JAVASCRIPT
JSON.stringify(await cioanalytics.webPush.subscription())

Send a real test delivery

  1. Create a test automation with a Web Push action and set its Sending behavior to Send Automatically. Queue Draft holds messages for review until you send them manually.
  2. Trigger the automation for your test profile. Use a trigger you control, like a test event, and keep the audience limited to your test profile.
  3. Check that the notification appears, and that clicking it opens your link.
  4. Open the automation’s Sent tab and find that delivery. Check Sent, then Delivered after the notification appears, and Opened after you click it.
Updated October 28, 2026