Notifications API
Real-time notification stream, unread counts, and preference management for debate activity.
The Notifications API provides real-time delivery of activity events (comments on your debates, forks) via Server-Sent Events (SSE), plus REST endpoints to list, mark-as-read, and configure your notification preferences.
Base URL
All endpoints below are relative to https://api.askverdict.ai. All notification endpoints require authentication via Authorization: Bearer <your_api_key>.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/notifications/stream | Open SSE stream for real-time push |
GET | /api/notifications/unread-count | Get current unread notification count |
GET | /api/notifications | List notifications (cursor paginated) |
PATCH | /api/notifications/read | Mark notifications as read |
GET | /api/notification-preferences | Get email notification preferences |
PATCH | /api/notification-preferences | Update email notification preferences |
GET | /api/unsubscribe | One-click email unsubscribe (no auth, HMAC token) |
GET /api/notifications/stream
/api/notifications/streamOpen a persistent Server-Sent Events (SSE) connection. The server pushes notification events in real time. Keepalive pings are sent every 30 seconds.
SSE connection lifecycle
The stream stays open until the client disconnects. Reconnect automatically using the browser EventSource API or the SDK's built-in reconnect logic. There is no message history — only events that arrive after you connect are delivered.
Response Headers
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: noExample Connections
// Browser EventSource
const es = new EventSource(
"https://api.askverdict.ai/api/notifications/stream",
{
withCredentials: true, // sends session cookie
}
);
es.addEventListener("connected", (e) => {
const data = JSON.parse(e.data);
console.log("Connected as user:", data.userId);
});
es.addEventListener("notification", (e) => {
const notification = JSON.parse(e.data);
console.log("New notification:", notification.type, notification.message);
});
es.addEventListener("ping", () => {
// Keepalive — no action needed
});
es.onerror = () => {
console.warn("SSE connection lost — EventSource will retry automatically");
};SSE Event Types
| Event | Description | Data |
|---|---|---|
connected | Fired once on successful connection | { "userId": "usr_abc123" } |
notification | A new notification has arrived | Notification object — see below |
ping | 30-second keepalive | Empty string |
Notification Object (SSE payload)
Notification Types
| Type | Trigger |
|---|---|
comment | A user commented on one of your debates |
fork | A user forked one of your public debates |
GET /api/notifications/unread-count
/api/notifications/unread-countLightweight endpoint for polling the number of unread notifications. Use this to update a badge or indicator without opening a full SSE stream.
Example Requests
curl "https://api.askverdict.ai/api/notifications/unread-count" \
-H "Authorization: Bearer vrd_your_api_key"Response
GET /api/notifications
/api/notificationsList your notifications in reverse-chronological order using cursor-based pagination. Returns both read and unread notifications alongside an overall unread count.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
cursor | string (ISO 8601 datetime) | Optional | Pagination cursor — the createdAt timestamp of the last item from the previous page. Omit for the first page. |
limit | integer | Optional | Maximum number of notifications to return. Between 1 and 50. Default: 20. |
Example Requests
# First page
curl "https://api.askverdict.ai/api/notifications?limit=20" \
-H "Authorization: Bearer vrd_your_api_key"
# Next page — use createdAt of last item as cursor
curl "https://api.askverdict.ai/api/notifications?cursor=2026-02-19T09:00:00.000Z&limit=20" \
-H "Authorization: Bearer vrd_your_api_key"Response
PATCH /api/notifications/read
/api/notifications/readMark notifications as read. Either supply a list of notification IDs to mark selectively, or set all: true to mark everything as read at once.
Request Body
The body is a discriminated union — send either ids or all: true.
Mark specific notifications
| Name | Type | Required | Description |
|---|---|---|---|
ids | string[] (UUID) | Required | Array of notification UUIDs to mark as read. Minimum 1, maximum 100. |
Mark all as read
| Name | Type | Required | Description |
|---|---|---|---|
all | true | Required | Pass true to mark all of your notifications as read at once. |
Example Requests
# Mark specific notifications
curl -X PATCH "https://api.askverdict.ai/api/notifications/read" \
-H "Authorization: Bearer vrd_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "ids": ["notif_1a2b3c4d", "notif_9e8d7c6b"] }'
# Mark all as read
curl -X PATCH "https://api.askverdict.ai/api/notifications/read" \
-H "Authorization: Bearer vrd_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "all": true }'Response
Error Responses
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Body does not match either expected shape — missing ids or all |
401 | UNAUTHORIZED | Missing or invalid API key |
Notification Preferences
Email notifications are controlled per-type. The preferences endpoints use a separate path (/api/notification-preferences) and are also authenticated.
GET /api/notification-preferences
/api/notification-preferencesRetrieve the authenticated user's email notification preferences.
Example Requests
curl "https://api.askverdict.ai/api/notification-preferences" \
-H "Authorization: Bearer vrd_your_api_key"Response
PATCH /api/notification-preferences
/api/notification-preferencesUpdate one or more email notification preference flags. Only the fields you supply are changed.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
emailComments | boolean | Optional | Receive email notifications when someone comments on your debates. |
emailForks | boolean | Optional | Receive email notifications when someone forks one of your public debates. |
Example Requests
curl -X PATCH "https://api.askverdict.ai/api/notification-preferences" \
-H "Authorization: Bearer vrd_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "emailForks": true }'Response
Returns the full updated preferences object:
GET /api/unsubscribe
/api/unsubscribeOne-click email unsubscribe endpoint. Linked from unsubscribe footers in notification emails. Verifies an HMAC token and disables the specified notification type. No authentication required.
Token security
The token parameter is an HMAC-SHA256 signature generated server-side. Do not construct unsubscribe links manually — only use links generated by AskVerdict notification emails.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
userId | string | Required | The user ID encoded in the unsubscribe link. |
type | "comments" | "forks" | Required | The notification type to unsubscribe from. |
token | string | Required | HMAC-SHA256 verification token generated from the notification email. |
Response
This endpoint returns an HTML page (not JSON) confirming the unsubscribe action. Returns 400 HTML on invalid or expired tokens.
Notification Object Reference
| Field | Type | Description |
|---|---|---|
id | string | Notification UUID |
type | "comment" | "fork" | Activity type that triggered the notification |
message | string | Human-readable notification message |
debateId | string | null | UUID of the related debate, if applicable |
actorId | string | null | User ID of the person who triggered the notification |
actorName | string | null | Display name of the actor |
read | boolean | Whether the notification has been marked as read |
createdAt | string (ISO 8601) | When the notification was created |
Notification Preferences Object Reference
| Field | Type | Description |
|---|---|---|
emailComments | boolean | Whether comment notification emails are enabled |
emailForks | boolean | Whether fork notification emails are enabled |
Was this page helpful?