Quick start

relaybell sends web push notifications to your users' browsers (desktop & Android) โ€” no app required. Two steps: add the SDK to collect subscribers, then call the API to send.

1. Add the SDK to your website

<script src="https://your-relaybell-host/relaybell-sdk.js"></script>
<script>
  RelayBell.init({ projectId: "YOUR_PROJECT_ID", apiBase: "https://your-relaybell-host" });
</script>

Find your projectId in the dashboard under Settings โ†’ API & SDK. The SDK shows your configured opt-in prompt and registers subscribers automatically.

โš ๏ธ Web push requires HTTPS (localhost is exempt for testing). You also host a tiny sw.js service worker at your site root โ€” copy it from this server's /sw.js.

2. Send a notification

curl -X POST https://your-relaybell-host/api/v1/notifications \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Hello ๐Ÿ‘‹","body":"Your first push","url":"https://example.com"}'

Authentication

Server-to-server requests authenticate with a project API key as a Bearer token. Generate one in Settings โ†’ API & SDK โ†’ Generate API key (shown once โ€” store it securely).

Authorization: Bearer rb_live_xxxxxxxxxxxxxxxx

Public, browser-side endpoints (subscribe, opt-in config) need only the projectId and are called by the SDK for you.

Send a notification

POST /api/v1/notifications  ยท  auth: Bearer API key

Queues a notification; the response returns immediately and delivery happens asynchronously.

JavaScript (Node)

const res = await fetch("https://your-relaybell-host/api/v1/notifications", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.RELAYBELL_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Flash sale ๐Ÿ”ฅ",
    body: "30% off ends tonight",
    url: "https://shop.example.com/sale",
    image: "https://cdn.example.com/sale.jpg",
    actions: [{ action: "a0", title: "Shop now", url: "https://shop.example.com" }],
  }),
});
const data = await res.json(); // { ok: true, notificationId, status }

Notification options

FieldTypeDescription
titlestringRequired. Notification title.
bodystringBody text (plain text; emoji supported).
urlstringOpened when the notification is clicked.
iconstring (URL)Small icon. Defaults to the project logo.
imagestring (URL)Large hero image (Chrome/Edge/Android).
badgestring (URL)Monochrome status-bar badge (mobile).
actionsarrayUp to 2 buttons: [{ action, title, url }].
requireInteractionbooleanKeep on screen until the user interacts.
tagstringReplace/group notifications with the same tag.
segmentIdstringSend only to a saved segment (see Targeting).
filtersobjectInline targeting rules (see Targeting).
sendAtISO dateSchedule for a future time (see Scheduling).

Targeting & segments

By default a send goes to all subscribers. Target a subset with a saved segmentId or inline filters.

{
  "title": "Pricing update",
  "filters": {
    "match": "all",
    "rules": [
      { "field": "country", "op": "eq", "value": "IN" },
      { "field": "url", "op": "contains", "value": "/pricing" },
      { "field": "tag:plan", "op": "eq", "value": "pro" }
    ]
  }
}

Fields: country, language, url, tag:KEY. Ops: eq, neq, contains, exists, not_exists. Match: all or any.

Scheduling

Add sendAt (ISO 8601) to schedule for later. The response status will be scheduled.

{ "title": "Good morning โ˜€๏ธ", "sendAt": "2026-06-24T03:30:00.000Z" }

Cancel a scheduled send: POST /api/v1/notifications/:id/cancel. Quiet hours (Settings) auto-defer immediate sends to the end of the window.

Tags & attributes

Attach custom data to subscribers from the browser to power segments:

RelayBell.setTags({ plan: "pro", city: "Mumbai" });

relaybell also auto-captures url (subscribe page), language, country (via CDN header), and device (desktop / android / ios).

Personalize with merge tags

Use any attribute or tag as a merge tag in a notification's title or body โ€” it is replaced per subscriber at send time. Add a fallback after a | for subscribers who don't have that value:

{"title":"Hi {name|there} ๐Ÿ‘‹","body":"Your {city} order has shipped"}

Set the values first with RelayBell.setTags({ name: "Asha", city: "Mumbai" }). A token with no value and no fallback renders empty โ€” so always give a fallback for tags not every subscriber has.

Image uploads

Host an image on relaybell and use the returned URL as an icon or image:

POST /api/v1/upload โ€” multipart field file (PNG/JPG/GIF/WebP, โ‰ค2 MB), auth: Bearer API key โ†’ { "url": "https://.../uploads/abc.png" }

SDK reference

RelayBell.init(options)

OptionDescription
projectIdRequired. Your project id.
apiBaseYour relaybell host (e.g. https://push.relaybell.com).
swPathService worker path (default /sw.js).
externalIdYour own user id, to tie a subscriber to your system.
tagsInitial tags object.

RelayBell.setTags(tags) ยท RelayBell.subscribeNow()

setTags updates custom attributes; subscribeNow forces the native permission prompt + subscription.

Responses & errors

All responses are JSON. Successful sends return 202 Accepted:

{ "ok": true, "notificationId": "โ€ฆ", "status": "queued" }   // or "scheduled"
StatusMeaning
400Invalid request (e.g. missing title).
401Missing/invalid API key.
404Project or resource not found.
202Accepted โ€” queued for delivery.

Need the marketing dashboard instead? Open the dashboard โ†’