Notifications feed
Me
Notifications feed
List, read, and delete the user’s in-app notifications. Backs the Notifications screen — match, message, listing, and tenancy alerts.
GET
Notifications feed
Overview
The in-app notification feed shown on the Notifications screen. Every event that wakes the device with a push (a new mutual match, new chat messages, a listing going live, tenancy status changes) also writes a persistent notification row for the recipient, so the feed and the push stay in sync. Each item carries aread flag. The client groups unread items under “New” and read items under “Earlier” (matching the Figma). unreadCount powers the bell badge on the home header.
Notifications are written best-effort alongside the domain write — a match/message is never rolled back if the feed write fails. Conversely, the global notification mute suppresses push delivery only; in-app notifications are still recorded so the user sees them when they open the app.
Notification types
type | Meaning | data deep-link |
|---|---|---|
MATCH_NEW | A new mutual match. | matchId |
MESSAGE_NEW | A new chat message. | conversationId, peerUserId |
LISTING_LIVE | The user’s listing went LIVE — visible to matches (onboarding complete AND tenancy approved). | — |
TENANCY_RECEIVED | Tenancy proof received / under review. | — |
TENANCY_APPROVED | Tenancy verification approved. | — |
TENANCY_REJECTED | Tenancy verification rejected — re-upload needed. | — |
SYSTEM | Generic / ops message. | — |
Authentication
Bearer <accessToken> required on every route. requireAuth + requireOnboarded applied.
GET /me/notifications — list
Newest-first, cursor-paginated by createdAt.
Query parameters
| Param | Type | Required | Notes |
|---|---|---|---|
limit | integer | no | Page size, 1..50. Default 20. |
before | string | no | Opaque cursor — pass the previous response’s nextCursor to fetch the next (older) page. |
Response — 200 OK
| Field | Type | Notes |
|---|---|---|
items[] | array | The notifications for this page. |
items[].id | string | Notification id. |
items[].type | string | One of the types above. |
items[].title | string | Bold headline (e.g. New Mutual Match!). |
items[].body | string | Supporting line(s). |
items[].data | object | Deep-link context (matchId / conversationId / peerUserId). |
items[].read | boolean | false → render under “New”. |
items[].createdAt | string | ISO timestamp; format relative client-side (“2 minutes ago”). |
nextCursor | string | null | Pass as before for the next page; null when exhausted. |
unreadCount | integer | Total unread for the bell badge. |
POST /me/notifications/:id/read — mark one read
Idempotent. Returns { "updated": boolean } (false if it was already read or not found). 200 OK.
POST /me/notifications/read-all — mark all read
Returns { "count": <number marked> }. 200 OK.
DELETE /me/notifications/:id — delete one
Idempotent. Returns { "removed": boolean }. 200 OK.
DELETE /me/notifications — clear all
Deletes every notification for the user. Returns { "count": <number removed> }. 200 OK.
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | limit out of range (1..50). |
| 401 | UNAUTHENTICATED | Missing, malformed, or expired access token. |
| 403 | ONBOARDING_INCOMPLETE | Caller has not finished onboarding. |
See also
- Toggle notification mute — suppresses push (not the in-app feed).
- Push notification fan-out — the device-push side of the same events.