Skip to content

Push notifications

Optional

Complete the Quick start first. Push is only needed for offline notifications.

Register device tokens so Sendsar can notify users when they are offline (no live WebSocket).

Simplest path (recommended)

After your app calls connect() with a session JWT, register push with:

ts
await client.registerDeviceToken({
  provider: "ONESIGNAL",
  token: subscriptionIdFromSdk,
  platform: "ios",
});

No extra backend route required. The gateway binds the token to the JWT user automatically.


How it works

  1. Your server upserts the user and mints a session JWT (Server setup).
  2. The client connects with that JWT.
  3. After the user opts in to push, call POST /users/me/device-tokens (or client.registerDeviceToken()).
  4. When a message is sent, online users get WebSocket events; offline users with a stored token get a push.

Push is not sent to users who are connected on a session JWT WebSocket for that tenant.


Prerequisites

StepWhoEndpoint
Tenant app + push configYour server (API key)POST /tenant-apps
User existsYour server (API key)POST /users
Session + connectClientYour session route + SDK connect()
Provider tokenClientFCM / OneSignal / etc. SDK

Provider support

providerStatus
ONESIGNALLive — use the OneSignal Subscription ID
FCM, PUSHY, APNSTokens stored; dispatch scaffolded

Register (client — session JWT)

POST {API_URL}/users/me/device-tokens

Headers: Authorization: Bearer <session-jwt>, Content-Type: application/json

FieldRequiredDescription
providerYesFCM, ONESIGNAL, PUSHY, or APNS
tokenYesProvider token or OneSignal subscription id
platformNoe.g. ios, android, web
ts
import Sendsar from "@sendsar/chat-sdk-javascript";

const chat = Sendsar.init({ apiUrl: "https://api.sendsar.com/v1" });
await chat.connect({ userId: chatUserId, token: sessionJwt });

await chat.registerDeviceToken({
  provider: "ONESIGNAL",
  token: oneSignalSubscriptionId,
  platform: "web",
});

Unregister: DELETE {API_URL}/users/me/device-tokens/{token} or chat.unregisterDeviceToken(token).


Register (server — API key)

Use when your backend holds the token instead of the client SDK.

POST {API_URL}/users/{userId}/device-tokens with x-api-key.

bash
curl -s -X POST "${SENDSAR_API_URL}/users/user_abc123/device-tokens" \
  -H "x-api-key: ${SENDSAR_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"provider":"ONESIGNAL","token":"…","platform":"ios"}'

Session JWT may also call POST /users/{userId}/device-tokens only when {userId} matches the token user (same rule as chat). Prefer /users/me/device-tokens from clients.


OneSignal

  1. Configure oneSignalConfig on a tenant app (POST /tenant-apps).
  2. Upsert the user with matching appCode (or use the default app).
  3. Pass the OneSignal SDK Subscription ID as token with provider: "ONESIGNAL".

Security

EndpointAPI keySession JWT
POST /users (upsert)YesNo
POST /users/me/device-tokensNoYes (own user only)
POST /users/:id/device-tokensYes (any user)Yes (only if :id is self)

Common issues

ProblemFix
401 on /me/device-tokensCall after connect(); check Bearer token
400 on /me/device-tokens with API key/me requires session JWT; use /:id with x-api-key from server
403 Cannot act as another userUse /me/... or match :id to JWT user
No pushUser still online on WebSocket, or missing tenant app config
OneSignal errorsSend Subscription ID, not legacy player id

API reference

Scalar docs under UsersPOST/DELETE /users/me/device-tokens and /:id/device-tokens.

See also Authentication and Server setup.

Sendsar — headless chat for B2B platforms