Notifications
The notification list and unread badge, push token registration, and push preferences.
The notification list and unread badge, push token registration, and push preferences.
Generated from the OpenAPI spec by
npm run docs:api -w api. Do not edit this page — change the decorators inapps/api/src/and regenerate.
Conventions
- Auth — a session on every route: the cookie on web, the bearer token on mobile. See Authentication.
- Errors — every non-2xx response has the body described in Errors.
- Types — a
?after a field name means it is optional;| nullmeans it is present but may be null. - Guide — Notifications and Live Updates.
Endpoints
GET /api/v1/notifications — The notification list
Newest first. Not cursor-paged — it returns a plain array capped by limit, because the bell shows a recent window rather than a scrollable history.
| Query | Type | Required | Notes |
|---|---|---|---|
limit | number | no | Rows per page. Defaults to 20, capped at 50. |
Returns 200 → NotificationResponse[]
| Error | When |
|---|---|
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
GET /api/v1/notifications/unread-count — How many are unread
Call on launch and on foreground. After that the badge is moved by the notification.created event on /api/v1/realtime/stream, so there is no need to poll this — and no reason to, since polling is what put a 30-second delay on the bell before the stream existed.
Returns 200 → CountResponse
| Error | When |
|---|---|
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
POST /api/v1/notifications/read — Mark read
Omit id to mark every unread notification read.
Body — MarkNotificationReadDto
Returns 204 → no body
| Error | When |
|---|---|
400 | The request was rejected. message is an array of field errors when validation failed. |
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
POST /api/v1/push/tokens — Register for push
Send the FCM registration token this client currently holds, on every launch — not only when permission is first granted. FCM rotates tokens, and a stale one stops receiving without saying so. Mobile clients must set platform, or the message is built for a browser and nothing is drawn while the app is backgrounded.
Body — RegisterPushTokenDto
Returns 204 → no body
| Error | When |
|---|---|
400 | The request was rejected. message is an array of field errors when validation failed. |
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
GET /api/v1/notifications/preferences — What this person has chosen to be interrupted by
Only the push leg is a preference. The bell has no switch: it is the record of what happened, and a notification nobody can see would be a bug rather than a setting. pushEnabled defaults to true for somebody who has never chosen.
Returns 200 → NotificationPreferencesResponse
| Error | When |
|---|---|
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
POST /api/v1/notifications/preferences — Turn browser and device push on or off
Turning push off stops the delivery and nothing else — notifications are still recorded and still appear on the bell. Registered tokens are left in place, so turning it back on does not require granting browser permission again.
Body — UpdateNotificationPreferencesDto
Returns 204 → no body
| Error | When |
|---|---|
400 | The request was rejected. message is an array of field errors when validation failed. |
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
DELETE /api/v1/push/tokens/{token} — Stop pushing to this client
Call on sign-out, before clearing the session — the route is guarded, and a token left behind keeps receiving somebody else’s notifications on a shared device.
| Path parameter | Type | Notes |
|---|---|---|
token | string | The FCM token to forget. |
Returns 204 → no body
| Error | When |
|---|---|
401 | No valid session. Clear the stored token and sign in again. |
403 | Signed in, but not allowed to do this. |
Data models
NotificationResponse
| Field | Type | Notes |
|---|---|---|
id | string | |
kind | mention | comment | reply | reaction | recognition | poll_closed | meeting | announcement | grievance | birthday | birthday_wish | birthday_thanks | Why the person is being told. Decides the icon and the wording. |
actor | MentionResponse | null | Who caused it, or null. null covers two cases on purpose, and a client cannot tell which: the account has been deleted, or naming the actor would give away something the recipient is not entitled to know. A grievance update is the second — it is signed by the team, never by the handler who made it. |
postId | string | null | What to open. Both are null on a notification with nothing to open. |
commentId | string | null | |
preview | string | A short excerpt of what was said, for the row's second line. |
readAt | string ISO 8601 | null | null while unread. |
createdAt | string ISO 8601 |
MentionResponse
| Field | Type | Notes |
|---|---|---|
id | string | |
name | string | |
image | string | null |
CountResponse
| Field | Type | Notes |
|---|---|---|
count | number |
MarkNotificationReadDto
| Field | Type | Notes |
|---|---|---|
id? | string | Omit to mark every unread notification read — what opening the bell does. |
RegisterPushTokenDto
| Field | Type | Notes |
|---|---|---|
token | string | The FCM registration token this client currently holds. · ≤ 500 chars |
platform? | web | ios | android | Which client the token came from. Decides the shape of the message FCM is asked to send, so a mobile app that omits it is treated as a browser and its notifications will not be drawn while it is backgrounded. Defaults to web so the existing web client keeps working unchanged. |
userAgent? | string | Free text identifying the client, shown to nobody — it is there to make a stale token traceable. Send the browser's user agent, or something like SuperPeople/1.2.0 (iPhone15,2; iOS 18.2) from a mobile build. · ≤ 400 chars |
previousToken? | string | The token this client held before FCM rotated it, if it knows of one. Sending it retires the old row now rather than leaving it to be found dead on some later send, by which point every notification in between has paid for a delivery attempt that could not succeed. It is only ever acted on when it belonged to the caller, so it cannot be used to switch off somebody else's browser. · ≤ 500 chars |
NotificationPreferencesResponse
| Field | Type | Notes |
|---|---|---|
pushEnabled | boolean | Whether browser and device push is on for this person. true for anybody who has never chosen. That costs nothing: push still cannot reach a browser that has not granted permission and registered a token, so the default only saves somebody who has just granted permission from hunting for a second switch. |
UpdateNotificationPreferencesDto
| Field | Type | Notes |
|---|---|---|
pushEnabled | boolean | Whether to interrupt this person with a browser or device notification. Turning it off stops the push and nothing else: the notification is still recorded and still appears on the bell, because that list is the record of what happened rather than a preference. |