Skip to main content

Overview

Notify is the web-push notification platform. Browsers never hold Notify secrets: a trusted product backend bridges every call server-to-server, so each browser talks only to its own same-origin product backend, which in turn talks to Notify with push-platform auth.

Architecture at a glance

The browser UI calls only its same-origin product backend, which holds its own bridge secrets (push-platform token; optional editor token) and forwards to notify-api. Notify delivers through notify-sender to the browser push service and service worker; interaction events flow back through the product backend to notify-api. Mongo: notify-api writes subscriptions_webpush and ingests interaction_events_webpush; notify-sender updates notifications_webpush after delivery.

The golden rule

danger

The browser calls only its own same-origin product backend. That backend calls Notify server-to-server with push-platform auth.

  • Never call Notify directly from the browser.
  • Never use player_id: 0 in a product integration — it is reserved for the internal dashboard smoke bucket.

Two-token auth model

Each token has a platform canonical name (what Notify stores) and a consumer copy (what your backend holds). The values must match; the env var names do not.

TokenYour backend (consumer)Notify platform (canonical)Used forRoutes
Push-platform authYour bearer token secret (name yours)NOTIFY_API_PUSH_PLATFORM_CALLERS_JSONbrowser lifecycleclient-config, subscriptions, deactivate, events/browser, events/semantic
Editor tokenYour editor bearer token (optional)INAPP_EDITOR_API_AUTH_TOKENadmin authoringtemplate CRUD, /api/v1/tenants/, /webpush/send, /webpush/activity
warning

Env-var NAME mismatch footgun. A consumer app names its own var differently (e.g. the dashboard uses NOTIFY_PUSH_PLATFORM_TOKEN) from the platform-side NOTIFY_API_PUSH_PLATFORM_CALLERS_JSON that Notify validates against. The consumer's token value must be listed as a token in that caller policy; the names differ because they belong to different services.

Current workspace status

lumio_admin_dashboard is the canonical committed Notify browser integration in this workspace today. The casino player-facing integration is in progress: online-services-front (React + Vite client) bridged through the online-services-player Node proxy, documented in Casino Integration.

Identity model

Every subscription, delivery, and event is scoped to a tenant and player. Your bridge sends tenant_id and player_id — both resolved server-side from trusted session/config, never from the browser.

FieldRule
tenant_idCasino/brand context from server config or session
player_idPositive integer from authenticated session/profile lookup

player_id: 0 is reserved for internal dashboard smoke tests only (lumio_admin_dashboard).

One player can have multiple active subscriptions (different browsers/devices). Delivery fans out to every active endpoint for that (tenant_id, player_id) pair.

Event trust split

ChannelRouteEventsVerified by
Browser telemetryevents/browserdisplayed / clicked / closedopaque interaction_token
Semantic app eventsevents/semanticopened / readexplicit tenant_id + positive player_id

These are separated because browsers can lie about semantics, so meaning-bearing events carry server-resolved identity. Telemetry is idempotent and non-mutating, so it is verified only by the opaque token Notify issued.

Where to go next

PageWhat it covers
Integration GuideBuild a new browser + backend integration end to end
API ReferenceEvery route, request/response, error code
Configuration & SecretsEnv vars, caller policy, VAPID, retention
Push Service Environment ConfigPer-environment vars your backend must configure
Reference: DashboardThe canonical working integration
Casino Integrationonline-services-front via the player Node proxy