Appearance
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
- Your server upserts the user and mints a session JWT (Server setup).
- The client connects with that JWT.
- After the user opts in to push, call
POST /users/me/device-tokens(orclient.registerDeviceToken()). - 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
| Step | Who | Endpoint |
|---|---|---|
| Tenant app + push config | Your server (API key) | POST /tenant-apps |
| User exists | Your server (API key) | POST /users |
| Session + connect | Client | Your session route + SDK connect() |
| Provider token | Client | FCM / OneSignal / etc. SDK |
Provider support
provider | Status |
|---|---|
ONESIGNAL | Live — use the OneSignal Subscription ID |
FCM, PUSHY, APNS | Tokens stored; dispatch scaffolded |
Register (client — session JWT)
POST {API_URL}/users/me/device-tokens
Headers: Authorization: Bearer <session-jwt>, Content-Type: application/json
| Field | Required | Description |
|---|---|---|
provider | Yes | FCM, ONESIGNAL, PUSHY, or APNS |
token | Yes | Provider token or OneSignal subscription id |
platform | No | e.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
- Configure
oneSignalConfigon a tenant app (POST /tenant-apps). - Upsert the user with matching
appCode(or use thedefaultapp). - Pass the OneSignal SDK Subscription ID as
tokenwithprovider: "ONESIGNAL".
Security
| Endpoint | API key | Session JWT |
|---|---|---|
POST /users (upsert) | Yes | No |
POST /users/me/device-tokens | No | Yes (own user only) |
POST /users/:id/device-tokens | Yes (any user) | Yes (only if :id is self) |
Common issues
| Problem | Fix |
|---|---|
401 on /me/device-tokens | Call 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 user | Use /me/... or match :id to JWT user |
| No push | User still online on WebSocket, or missing tenant app config |
| OneSignal errors | Send Subscription ID, not legacy player id |
API reference
Scalar docs under Users — POST/DELETE /users/me/device-tokens and /:id/device-tokens.
See also Authentication and Server setup.