Notifications
Notify users about activity relevant to them, and manage per-category notification preferences.
Notifications inform users about activity relevant to them across their boards — invites, meeting and dashboard activity, report publication, and more. Notifications can be marked as read individually or in bulk, deleted, and each user can control which channels (email, in_app) a given event category delivers to.
Legacy endpoints
All six endpoints below are legacy — their paths do not carry a /api/v1
prefix and are not reachable at one. See
Versioning for what "legacy" means in this
API.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/notification/ | List notifications |
PUT | /api/notification/read/all | Mark all notifications as read |
PUT | /api/notification/read/:notificationId | Mark a single notification as read |
DELETE | /api/notification/:notificationId | Delete a notification |
GET | /api/notification/preferences | Get notification preferences |
PUT | /api/notification/preferences | Update a notification preference |
Notification Object
{
"_id": "60d5ec49f1a2c8b1f8e4e1a1",
"userId": "507f1f77bcf86cd799439011",
"type": "board_invite",
"message": "You have been invited to join Acme Corp board.",
"boardId": { "_id": "60d5ec49f1a2c8b1f8e4e1b1", "name": "Acme Corp Board" },
"inviterId": {
"_id": "507f1f77bcf86cd799439012",
"firstName": "Alex",
"lastName": "Admin"
},
"read": false,
"avatar": "https://.../signed-s3-url",
"createdAt": "2025-06-01T10:00:00.000Z",
"updatedAt": "2025-06-01T10:00:00.000Z"
}Fields
| Field | Type | Description |
|---|---|---|
_id | string | Opaque notification ID |
userId | string | The user this notification belongs to |
type | string | Notification type — see values below |
message | string | Human-readable notification message |
read | boolean | Whether the notification has been read (default false) |
createdAt | string | ISO-8601 timestamp |
updatedAt | string | ISO-8601 timestamp |
There is no single generic "resource ID" field. Depending on type, one or more of the following optional fields are present, and the list endpoint populates the referenced document into an object (as shown for boardId/inviterId above) rather than leaving it a bare ID string: boardId, inviterId, inviteId, acceptingUserId, triggeringUserId, meetingLink, reportId, dashboardId, dashboardType, documentId, cycleId, sectionName, betId. The list endpoint also computes an avatar field (a signed URL) from whichever user reference is relevant.
Type Values
board_invite, membership_accepted, membership_modified, membership_removed, member_left, board_update, new_comment, task_assignment, ownership_transfer, slot_proposed, dashboard_assigned, dashboard_access_granted, dashboard_access_removed, dashboard_changes_requested, dashboard_ready_for_review, dashboard_internally_reviewed, report_published, report_finalized, example_board_ready, merge_recommendation, meeting_creation_suggestion, section_dispatched, section_reminder, post_meeting_minutes_distributed, validation_flag_raised, package_published, bet_due_soon, meeting_rsvp_changed, meeting_updated_from_calendar, meeting_cancelled_from_calendar
List Notifications
GET /api/notification/Returns all notifications for the authenticated user, ordered by most recent first, with related documents populated.
Response
Returns a bare array — not wrapped in { "data": ... }:
[
/* array of notification objects */
]Errors
| Code | Status | When |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid token |
Mark All Notifications as Read
PUT /api/notification/read/allResponse
{ "message": "All notifications for user marked as read" }Errors
| Code | Status | When |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid token |
Mark a Single Notification as Read
PUT /api/notification/read/:notificationIdResponse
Returns the updated notification object with read: true.
Errors
| Code | Status | When |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid token |
RESOURCE_NOT_FOUND | 404 | Notification does not exist |
Delete a Notification
DELETE /api/notification/:notificationIdDeletes a notification. JWT-only — API tokens cannot call this endpoint.
Response
{ "message": "Notification deleted successfully" }Errors
| Code | Status | When |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid token, or called with an API token |
RESOURCE_NOT_FOUND | 404 | Notification does not exist |
Get Notification Preferences
GET /api/notification/preferencesReturns only the categories the user has explicitly overridden — a category absent from the response is using its default channels.
Response
Bare object, not wrapped in { "data": ... }:
{
"preferences": {
"action_item": ["email", "in_app"],
"bet_reminder": []
}
}preferences maps an event category to the list of channels (email, in_app) it delivers to. An empty array silences that category entirely.
Event Categories
section_status, validation_flag, package_status, post_meeting, action_item, bet_reminder, section_overdue
Errors
| Code | Status | When |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid token |
Update a Notification Preference
PUT /api/notification/preferencesUpserts the channel list for one event category.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
eventCategory | string | Yes | One of the event categories above |
channels | string[] | Yes | Subset of email, in_app; pass [] to silence the category |
Response
Returns the full updated { "preferences": { ... } } map, in the same shape as the GET response.
Errors
| Code | Status | When |
|---|---|---|
INVALID_REQUEST_BODY | 400 | Invalid eventCategory or channels value |
UNAUTHENTICATED | 401 | Missing or invalid token |