# relaybell — complete documentation for AI assistants
> relaybell is a web push notification service for any website, WordPress, or Shopify store — it lets you re-engage visitors with browser push notifications, with no email address or app install required. Visitors opt in with one click; you reach them again even when they've left your site. Operated by Nexistech (https://nexistech.in).
Updated: 2026-10-20
relaybell is an alternative to OneSignal and PushEngage. Core capabilities: an opt-in prompt and browser SDK, broadcasts with personalization/emoji/A-B testing, sends to one signed-in user by your own user id (transactional messages), audience segments and tags, automations (welcome series, event-triggered reminders like abandoned-cart, back-in-stock and price-drop alerts, recurring campaigns, RSS-to-push), on-site banner/slide-in messages, conversion goals, scheduled email reports, outbound webhooks, and GDPR/CCPA compliance tools. WordPress and WooCommerce are supported via an official plugin; Shopify via a storefront snippet plus commerce webhooks (push on Shopify needs a custom domain, set up by the relaybell team). This file holds the key facts, the full developer documentation (https://relaybell.com/docs), the plain-language setup guide (https://relaybell.com/guide), the plans (https://relaybell.com/pricing) and a list of every REST endpoint (https://relaybell.com/docs/api). The shorter index is https://relaybell.com/llms.txt.
## Key facts for assistants
- Base URL: https://relaybell.com is the only host (there are no api., cdn. or push. subdomains). The REST API is at https://relaybell.com/api/v1/…
- Auth: each website (project) has its own secret API keys, starting `rb_live_`, sent as `Authorization: Bearer rb_live_…`. Create one in the dashboard under Settings → Developers → API keys (signing up doesn't create one, and a key can't create keys). Each key has scopes — `full`, `send`, `events:write`, `subscribers:read`, `subscribers:write`, `segments:write`, `settings:write`, `webhooks:write` — and an optional expiry; a call outside its scopes answers `403 insufficient_scope` with the scope in `required`. Keys are for servers only — never put one in browser code.
- Browser SDK: a script tag, not an npm package — `` then ``. The Project ID is on the dashboard's Install page (and under Settings → Developers). `apiBase` is optional: left out, it is the address the script was loaded from.
- Service worker: the site must also serve relaybell's `sw.js` from its own domain, normally at the root (https://yoursite.com/sw.js; download it from https://relaybell.com/sw.js). Without it push can't work. In a folder instead, pass `swPath` (and `swScope`) to `init()`. The WordPress plugin serves its own, so WordPress sites skip this. Shopify can't host it (see Shopify below).
- Server SDKs: npm `relaybell` (Node.js), PyPI `relaybell` (Python), Composer `relaybell/relaybell-php` (PHP). All are server-side only and need the API key; none of them runs in the browser.
- Send: `POST /api/v1/notifications` with `{ "title", "body", "url", … }` answers 202 `{ "ok": true, "notificationId", "status" }` (`status` is "queued", "scheduled" — a future `sendAt` or quiet hours — or "held_for_review" for a new account's first large broadcast). No targeting fields = every subscriber of that website. Field names are camelCase in every SDK; a snake_case targeting field such as `external_id` is refused with `400 unknown_field`. To one user: add `"externalId": ""` (or `"externalIds": [...]`) and, for order updates and alerts, `"transactional": true`. Cancel a scheduled send with `POST /api/v1/notifications//cancel`.
- Targeting: `segmentId`, or inline `filters` = `{ "match": "all" | "any", "rules": [{ "field", "op", "value" }] }` with fields `country`, `language`, `url`, `external_id`, `tag:KEY` and ops `eq`, `neq`, `contains`, `in`, `exists`, `not_exists` (`eq`, `neq` and `in` are exact and case-sensitive; country codes are upper case, e.g. `IN`); plus `topicId` (id or slug) and `excludeSegmentId` / `excludeFilters`. An unknown field, or a missing segment, matches nobody — never everyone.
- Personalization: `{key}` or `{key|fallback}` in a send's title, body or url — the subscriber's tags plus `external_id`, `url`, `language` and `country`. In automation and journey messages the same tags take the triggering event's properties (e.g. `{product}`, `{url}`).
- Events & automations: your server sends `POST /api/v1/events` `{ "event", "externalId", "properties" }` (scope `events:write`); pages call `RelayBell.track(event, properties)`, which counts only for a browser with a push subscription. Automations (`/api/v1/automations`) send one push per event with `delaySeconds`, `cancelOn` (e.g. a `purchase` cancels a cart reminder), `conditions` on the event's properties and `oncePerSubscriber`; journeys (`/api/v1/sequences`) send several steps and start only once per subscriber.
- Linking a browser to your user id: `externalId` in `RelayBell.init()` or `RelayBell.identify(externalId, userHash)`; `userHash` is the lowercase hex HMAC-SHA256 of the id, keyed with the website's identity secret (Settings → Developers → User ID verification), made on your server. A browser with no id yet joins that user; a browser already linked to another id moves only with a valid userHash (an account switch on a shared browser).
- Webhooks are signed: verify header `X-Relaybell-Webhook-Signature: t=,v1=.", keyed with the whole webhook secret, whsec_ prefix included>` with a 5-minute timestamp tolerance and a constant-time compare (the server SDKs 1.2.0 have verifyWebhook / verify_webhook / Relaybell\Webhook::verify). The older `X-Relaybell-Signature: sha256=` is still sent. Failed deliveries (no 2xx within 10 s) are retried 5 times over about 10 hours (1 min, 5 min, 30 min, 2 h, 8 h); `X-Relaybell-Delivery` stays the same across retries, so de-duplicate by it; a 410 answer stops retries. Deliveries are logged for 30 days (GET /api/v1/webhooks/:id/deliveries, resend, POST /api/v1/webhooks/:id/test), and a webhook failing for 3 days or 50 deliveries in a row is turned off.
- Limits: 60 sends a minute and 600 an hour per API key; per website, 30 broadcasts and 1,000 sends to specific users per clock hour (`429 send_limit_reached`, with `Retry-After`). Every error code: https://relaybell.com/docs/errors-limits
## How-to answers
- **Install on a plain website:** paste the relaybell SDK snippet before `