Skip to main content

Overview

The Notifications API allows you to retrieve and manage user notifications for video views, comments, reactions, and replies.

Endpoints

Get Notifications

Retrieve all notifications for the authenticated user.
GET /api/notifications
authorization
string
required
Bearer token for authentication

Response

notifications
array
Array of notification objects
count
object
Record of notification counts by type

Example Request

curl -X GET "https://cap.so/api/notifications" \
  -H "Authorization: Bearer <token>"

Example Response

{
  "notifications": [
    {
      "id": "notif_123",
      "type": "comment",
      "videoId": "vid_456",
      "author": {
        "id": "user_789",
        "name": "John Doe",
        "avatar": "https://example.com/avatar.jpg"
      },
      "comment": {
        "id": "comment_321",
        "content": "Great video!"
      },
      "readAt": null,
      "createdAt": "2024-02-28T12:00:00Z"
    },
    {
      "id": "notif_124",
      "type": "view",
      "videoId": "vid_456",
      "author": {
        "id": "user_790",
        "name": "Jane Smith",
        "avatar": null
      },
      "readAt": "2024-02-28T13:00:00Z",
      "createdAt": "2024-02-28T12:30:00Z"
    }
  ],
  "count": {
    "comment": 5,
    "view": 23,
    "reaction": 8,
    "reply": 2
  }
}

Notification Types

Notifications can be one of four types:

View Notification

Someone viewed your video.
{
  type: "view",
  videoId: string,
  author: NotificationAuthor,
  id: string,
  readAt: Date | null,
  createdAt: Date
}

Comment Notification

Someone commented on your video.
{
  type: "comment",
  videoId: string,
  author: NotificationAuthor,
  comment: {
    id: string,
    content: string
  },
  id: string,
  readAt: Date | null,
  createdAt: Date
}

Reaction Notification

Someone reacted to your video comment.
{
  type: "reaction",
  videoId: string,
  author: NotificationAuthor,
  comment: {
    id: string,
    content: string
  },
  id: string,
  readAt: Date | null,
  createdAt: Date
}

Reply Notification

Someone replied to your comment.
{
  type: "reply",
  videoId: string,
  author: NotificationAuthor,
  comment: {
    id: string,
    content: string
  },
  id: string,
  readAt: Date | null,
  createdAt: Date
}

Notification Schema

NotificationAuthor

Information about the user who triggered the notification.
id
string
required
Unique identifier of the author
name
string
required
Display name of the author
avatar
string | null
required
URL to the author’s avatar image, or null if not set

NotificationBase

Base fields present on all notifications.
id
string
required
Unique identifier of the notification
readAt
Date | null
required
Timestamp when the notification was read, or null if unread
createdAt
Date
required
Timestamp when the notification was created

CommentData

Comment information included in comment, reaction, and reply notifications.
id
string
required
Unique identifier of the comment
content
string
required
Text content of the comment

Implementation Details

The notifications endpoint is defined in packages/web-api-contract/src/index.ts:91-102:
notifications: c.router({
  get: {
    method: "GET",
    path: "/notifications",
    responses: {
      200: z.object({
        notifications: z.array(Notification),
        count: z.record(z.string(), z.number()),
      }),
    },
  },
})
Notification types are defined in packages/web-api-contract/src/index.ts:5-59:
export const NotificationAuthor = z.object({
  id: z.string(),
  name: z.string(),
  avatar: z.string().nullable(),
});

export const NotificationBase = z.object({
  id: z.string(),
  readAt: z.coerce.date().nullable(),
  createdAt: z.coerce.date(),
});

export const Notification = z
  .union([
    z.object({
      type: z.literal("view"),
      videoId: z.string(),
      author: NotificationAuthor,
    }),
    z.object({
      type: z.literal("comment"),
      videoId: z.string(),
      author: NotificationAuthor,
      comment: CommentData,
    }),
    // ...
  ])
  .and(NotificationBase);

Notification Preferences

Users can manage notification preferences through a separate endpoint:
POST /api/notifications/preferences
Preferences are stored in the user’s profile:
interface NotificationPreferences {
  notifications: {
    pauseComments: boolean;
    pauseReplies: boolean;
    pauseViews: boolean;
    pauseReactions: boolean;
  };
}

Error Responses

401 Unauthorized

{
  "error": "Unauthorized"
}
Authentication required or token invalid.

500 Internal Server Error

{
  "error": "Internal server error",
  "message": "Failed to fetch notifications"
}
An unexpected error occurred on the server.

Usage Example

TypeScript Client

import { contract } from "@cap/web-api-contract";
import { initClient } from "@ts-rest/core";

const client = initClient(contract, {
  baseUrl: "https://cap.so/api",
  baseHeaders: {
    Authorization: `Bearer ${token}`,
  },
});

const { status, body } = await client.notifications.get();

if (status === 200) {
  console.log(`You have ${body.notifications.length} notifications`);
  console.log(`Unread comments: ${body.count.comment || 0}`);
}

Filter Unread Notifications

const unread = body.notifications.filter((n) => n.readAt === null);
console.log(`${unread.length} unread notifications`);

Group by Type

const grouped = body.notifications.reduce((acc, notification) => {
  if (!acc[notification.type]) {
    acc[notification.type] = [];
  }
  acc[notification.type].push(notification);
  return acc;
}, {} as Record<string, typeof body.notifications>);

console.log(`Comments: ${grouped.comment?.length || 0}`);
console.log(`Views: ${grouped.view?.length || 0}`);

Next Steps

Authentication

Learn about authentication methods

Videos

Manage videos via API

Build docs developers (and LLMs) love