Quickstart
relaybell adds web push notifications to any website. Drop in a snippet, and you can collect subscribers and send notifications โ with automation, targeting, and analytics โ in minutes.
Grab your Project ID and an API key from your dashboard (Settings โ API keys), then:
<script src="https://relaybell.com/relaybell-sdk.js"></script>
<script>
RelayBell.init({ projectId: "YOUR_PROJECT_ID", apiBase: "https://relaybell.com" });
</script>
That's the whole install. relaybell shows your opt-in prompt, subscribes visitors, and stores them. To send, POST to the REST API with your API key (see Sending).
Installing the SDK
The SDK needs a service worker at your site root. If you use the hosted relaybell-sdk.js, the default swPath is /sw.js โ host our sw.js there, or pass a custom path. On WordPress/Shopify our plugins/snippets handle this for you.
Browser SDK โ init & options
RelayBell.init({
projectId: "YOUR_PROJECT_ID", // required
apiBase: "https://relaybell.com",
swPath: "/sw.js", // service-worker path
externalId: "user_123", // link this browser to your own user id
tags: { plan: "pro" }, // custom attributes for segmentation
requireConsent: false, // true = wait for grantConsent() (CMP integration)
policyVersion: "2026-01" // recorded with consent for your audit trail
});
Browser SDK โ methods
| Method | What it does |
|---|---|
init(opts) | Registers the SW, shows the opt-in prompt, subscribes. |
subscribeNow() | Triggers the browser permission prompt (call from a click). |
unsubscribe() | Opts the visitor out and suppresses future sends. |
isSupported() | { supported, browser, os, needsInstall } โ feature detection. |
setTags({...}) | Update custom attributes for segmentation. |
setTopics(["news"]) | Save which topics the subscriber wants. |
showPreferences() | Opens a preference-center modal of your topics. |
showInbox() | Opens a modal of your recent notifications. |
track(event, props) | Send a behavioral event (fires automations + attribution). |
trackConversion(value, props) | Record a purchase/conversion with revenue. |
grantConsent() / revokeConsent() | For cookie-consent (CMP) gating when requireConsent is set. |
// Behavioral tracking โ powers cart abandonment, back-in-stock, attribution
RelayBell.track("cart.updated", { product: "Blue Shoes", price: 49, url: location.href });
RelayBell.trackConversion(79.99, { orderId: "A123" });
Opt-in prompts
Prompt style, copy, trigger and colors are configured per project (dashboard, or PUT /api/v1/prompt). Styles: slidein (default), bar, modal, native. Triggers: delay, load, click, scroll, exit. Add a privacyUrl (Settings โ Compliance) to show a privacy link. Set a prompt b variant to A/B-test opt-in copy.
REST API โ authentication
All server-side calls use a Bearer API key (starts with rb_live_):
curl https://relaybell.com/api/v1/stats \
-H "Authorization: Bearer rb_live_xxxxx"
Sending notifications
POST /api/v1/notifications โ returns 202, delivered asynchronously.
curl -X POST https://relaybell.com/api/v1/notifications \
-H "Authorization: Bearer rb_live_xxxxx" -H "Content-Type: application/json" \
-d '{
"title": "Flash sale ๐ฅ",
"body": "30% off ends tonight โ {name|there}!",
"url": "https://shop.example/sale"
}'
| Field | Description |
|---|---|
title * | Notification title. Supports {merge} tags. |
body, url, icon, image, badge, tag | Rich content. requireInteraction keeps it sticky. |
actions | Up to 2 buttons: [{action,title,url}]. |
segmentId / filters | Target a saved segment or inline filters. |
topicId | Target subscribers of a topic. |
excludeSegmentId / excludeFilters | Suppress a segment from this send. |
sendAt | ISO timestamp to schedule. |
perTimezone + localTime | Deliver at a local time (e.g. "09:00") per subscriber. |
smartTime | Deliver at each subscriber's most-active hour. |
ttl | Time-to-live in seconds (default 24h). |
translations | { "es": {title,body}, ... } โ auto-picked by subscriber language. |
ab | A/B test: { "b": { title, body, url, image } }. |
abTest | Auto-winner: { autoWinner:true, testPercent:20, afterHours:4 } โ tests, then sends the winner to the rest. |
Events & automation
POST /api/v1/events โ send a behavioral event (server-side; the browser SDK's track() does this too).
{ "event": "purchase", "externalId": "user_123", "properties": { "value": 79.99 } }
Automations (/api/v1/automations) fire a push when an event happens, with an optional delay and a cancelOn event. This powers cart abandonment (a purchase cancels the reminder), back-in-stock, price-drop, and welcome-back flows. A purchase with a value is attributed as a conversion to the last notification delivered to that subscriber.
POST /api/v1/automations
{ "name":"Cart abandon", "event":"cart.updated", "delaySeconds":3600,
"cancelOn":"purchase", "action":{ "title":"You left {product} ๐", "url":"{url}" } }
Drip sequences
/api/v1/sequences โ multi-step journeys. Subscribers enter on subscribe or on an event, then flow through steps with per-step delays; cancelOn drops them if they convert.
POST /api/v1/sequences
{ "name":"Welcome series", "trigger":"subscribe", "cancelOn":"purchase",
"steps":[ { "delaySeconds":0, "title":"Welcome ๐" },
{ "delaySeconds":86400, "title":"Here's how to start" },
{ "delaySeconds":604800, "title":"A little something for you" } ] }
Segments & topics
/api/v1/segmentsโ saved filters over country, language, url, and customtag:KEY(ops: eq, neq, contains, exists).POST /segments/previewreturns a live match count./api/v1/topicsโ preference-center categories. Subscribers opt in viaRelayBell.setTopics()/showPreferences(); target withtopicId.GET /api/v1/subscribers/exportโ CSV of subscribers.POST /api/v1/subscribers/importโ enrich/pre-seed by external ID with tags + topics (push tokens can't be imported across origins).
Analytics & webhooks
GET /api/v1/statsโ subscribers, sent, delivered (receipts), clicks, CTR, conversions, revenue, per-notification + A/B breakdowns.- Webhooks (
/api/v1/webhooks) โ HMAC-signed POSTs forsubscriber.created,subscriber.unsubscribed,notification.sent,notification.clicked. Verify with theX-Relaybell-Signatureheader. - RSS โ push (
/api/v1/feeds) and recurring campaigns (/api/v1/schedules). - AI copy โ
POST /api/v1/ai/suggestwith{title, body}returns 3 punchier variants.
Errors, rate limits & webhook verification
Errors return a JSON body { "error": "code" } with a standard HTTP status โ 400 invalid input, 401 bad/missing key, 403 unverified sender or suspended account, 404 not found, 429 rate-limited. The API is rate-limited per IP; back off and retry on 429.
Sending rules: quiet hours and a per-subscriber daily frequency cap are set per project (Settings โ Sending rules) and applied automatically to every send โ no per-request flags needed.
Verify a webhook signature
Every webhook is signed with your webhook secret. Check the X-Relaybell-Signature header (sha256=<hex>) against the raw request body:
const crypto = require("crypto");
const sig = req.headers["x-relaybell-signature"]; // "sha256=abc123โฆ"
const expected = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody).digest("hex");
if (crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
// trusted โ handle req.body.event
}
Compliance / GDPR
relaybell records consent (time, page, policy version) on opt-in. For data-subject requests:
GET /api/v1/subscribers/:externalId/dataโ export everything held about a subscriber (right to access).DELETE /api/v1/subscribers/:externalIdโ erase all of it (right to erasure).- Set a retention window (Settings โ Compliance) to auto-prune old event logs. See our Privacy Policy and DPA.
WordPress & WooCommerce
Install the relaybell WordPress plugin: set your Project ID + API key, and it injects the SDK, serves the service worker, and can auto-send a push when you publish. With WooCommerce active, it also fires purchase, cart.updated, and back_in_stock events automatically.
Shopify
Two parts: (1) add the storefront snippet from integrations/shopify/snippet.liquid to your theme to collect subscribers; (2) point your Shopify webhooks at https://relaybell.com/api/v1/integrations/shopify/<PROJECT_ID>. Topics are mapped automatically:
| Shopify topic | relaybell event |
|---|---|
checkouts/create, checkouts/update | cart.updated |
orders/paid | purchase (value = total) |
orders/fulfilled | order.fulfilled |
Set a Shopify webhook secret (Settings โ Compliance) to verify signatures.
Google Tag Manager
Add a Custom HTML tag in GTM, set to fire on All Pages:
<script src="https://relaybell.com/relaybell-sdk.js"></script>
<script>
window.addEventListener('load', function () {
RelayBell.init({ projectId: "YOUR_PROJECT_ID", apiBase: "https://relaybell.com" });
});
</script>
Server SDKs
Thin wrappers over the REST API โ install from your package manager:
| Language | Install |
|---|---|
| Node.js | npm install relaybell |
| Python | pip install relaybell |
| PHP | composer require relaybell/relaybell-php |
Prefer no package manager? Zipped builds are also available: Node ยท PHP ยท Python.
// Node
const { RelayBell } = require("relaybell");
const rb = new RelayBell({ apiKey: "rb_live_xxxxx" });
await rb.send({ title: "Hello", body: "World", url: "https://example.com" });
await rb.track("purchase", { externalId: "user_123", properties: { value: 42 } });
# PHP
$rb = new Relaybell\Client("rb_live_xxxxx");
$rb->send(["title" => "Hello", "body" => "World", "url" => "https://example.com"]);
# Python
from relaybell import RelayBell
rb = RelayBell("rb_live_xxxxx")
rb.send(title="Hello", body="World", url="https://example.com")
Zapier
Connect relaybell to thousands of apps with no code. Actions: Send Notification and Track Event; trigger: New Subscriber. Add it when building a Zap by searching relaybell and connecting with your API key. note the public-directory listing is completing Zapier's review; until then, connect via the invite link from your relaybell Zapier app.
Browser support
Standards-based Web Push (VAPID) works on Chrome, Firefox, Edge, Opera, Samsung Internet, and Brave (desktop & Android), and Safari 16.1+ on macOS 13 (Ventura) and later, plus Safari on iOS/iPadOS 16.4+ (iPhone/iPad requires adding the site to the Home Screen, which the SDK guides). Dead subscriptions are pruned automatically.