---
title: "Read Speak AI in-app notifications with the API"
description: "List the in-app notifications in your Speak AI account, filter them by category such as label or comment activity, and mark your own as read."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.speakai.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Read Speak AI in-app notifications with the API


import EndpointIndex from "@/components/api/EndpointIndex.astro";

The Speak AI API exposes 2 notifications endpoints under the base URL `https://api.speakai.co/v1`. Every request needs the `x-speakai-key` and `x-access-token` headers described in [Authentication](/api/authentication/).

The in-app notifications the Speak app lists under **Notifications**: uploads and analysis, payments, team changes, and label and comment activity. Read them a page at a time with filters, and mark your own as read.

## What can you do with the notifications endpoints?

Speak AI groups these 2 endpoints under the notifications resource. Each entry below links to the full reference for that endpoint further down this page.

### Notifications

| Method | Path | What it does |
| --- | --- | --- |
| `GET` | [`/notification`](#get-notification) | List notifications |
| `PUT` | [`/notification`](#put-notification) | Mark notifications as read |

## Notifications

<h2 id="get-notification">List notifications</h2>

Returns your company's in-app notifications, newest first, a page at a time. The Speak app shows the same list under **Notifications**.

#### Who sees what

An owner sees every notification in the company. A member of one or more user groups sees their own notifications, the ones written for the people in those groups, and the ones assigned to those groups. Anyone else sees every notification in the company. `filterUserId` narrows the list to one person.

`totalUnReadCount` always counts only your own unread notifications, whatever filters you send.

#### Categories and actions

`type` is the category of a notification and `action` is what happened. Send either as a filter. An unknown `type` is ignored and returns every category, while an unknown `action` matches nothing.

#### Labels and comments

- **Label library**: creating, editing, archiving, restoring or merging a label, or adding Speak label sets, writes `type` `label` with `mediaType` `label` for the person who made the change. `mediaId` holds the `labelId`.
- **Labels on a transcript**: applying, changing or removing labels writes `type` `label` with actions `created`, `updated` or `deleted`. `mediaId` and `mediaType` name the file.
- **Comments**: adding, editing, resolving, reopening or deleting a comment writes `type` `comment` for the person who did it, with actions `created`, `updated`, `resolved`, `reopened` or `deleted`.
- **Thread starters**: the person who started a thread also gets a `comment` notification when someone else replies (`replied`), resolves it (`resolved`) or reopens it (`reopened`). They are not told about their own replies, and people who are no longer active members are not told.
- **Dashboard share links**: turning labels or comments on or off on a dashboard's share link, or changing its modes or reviewer names, writes `type` `dashboard` with `mediaType` `dashboard`, and `mediaId` holds the `dashboardId`.

Changes made through a dashboard share link are written for the link's owner and end with "by \<name> from a shared dashboard".

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | No | Page to return, counting from 0. Leave it out for the first page. |
| `pageSize` | query | integer | No | Notifications per page. Leave it out for 50. |
| `type` | query | string | No | Only this category. One of the `type` values listed in the response schema, such as `label`, `comment` or `dashboard`. Any other value is ignored. |
| `action` | query | string | No | Only this action, such as `replied`, `resolved` or `reopened`. Matched exactly. |
| `description` | query | string | No | Text to look for in the description, ignoring case. |
| `filterUserId` | query | string | No | Only notifications written for this user id. |
| `startDate` | query | string (date-time) | No | Start of a date range on `createdAt`. Applied only together with `endDate`. |
| `endDate` | query | string (date-time) | No | End of a date range on `createdAt`. Applied only together with `startDate`. |
| `sortBy` | query | string | No | Field to sort by. Leave it out to sort by `createdAt`, newest first. Any other value is ignored. |
| `sortDir` | query | string | No | `asc` for ascending. Anything else sorts descending. |

<div slot="code">

<CodePanel label="Example request">

```bash
curl -X GET 'https://api.speakai.co/v1/notification?page=0&pageSize=50&type=comment&action=replied&description=Customer%20call&filterUserId=65f0c1a2b3c4d5e6f7a8b9c0&startDate=2026-10-01T00%3A00%3A00.000Z&endDate=2026-10-07T23%3A59%3A59.000Z&sortBy=createdAt&sortDir=desc' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
```

</CodePanel>

<ResponsePanel id="get-notification" statuses={[{"code":"200","description":"Success"}]}>

<div slot="status-200">

**`200` Success**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | `success` on every 2xx response. One of: `success` . |
| `data` | object |  |
| `data.totalCount` | integer | How many notifications match the filters, across all pages. |
| `data.totalUnReadCount` | integer | How many of your own notifications are unread. |
| `data.notificationList` | object[] | This page of notifications. |

<details>
<summary>`data.notificationList` -- 12 more fields</summary>

| Field | Type | Description |
| --- | --- | --- |
| `_id` | string | Id of the notification. |
| `mediaId` | string | Id of what the notification is about: a media file, or a `labelId` when `mediaType` is `label`, or a `dashboardId` when `mediaType` is `dashboard`. Left out when it is about nothing in particular. |
| `mediaType` | string | What kind of thing `mediaId` names: `audio`, `video` or `text` for a file, `label` for a label or group, `dashboard` for a dashboard. Left out when there is no `mediaId`. |
| `description` | string | What happened, in words you can show to a person. |
| `type` | string | Category. One of: `clip`, `audio`, `account`, `automation`, `embed`, `integration`, `magic prompt`, `media`, `payment`, `presentation`, `recorder`, `survey`, `subscription`, `team`, `text`, `transcription`, `translate`, `video`, `zapier`, `meeting assistant`, `google calendar`, `outlook calendar`, `auto reload`, `folder`, `fields`, `assistant template`, `knowledge base`, `label`, `comment`, `dashboard` . |
| `action` | string | What happened. One of: `analyzed`, `created`, `credit`, `debit`, `deleted`, `export`, `paid`, `updated`, `uploaded`, `error`, `failed`, `cloned`, `replied`, `archived`, `restored`, `merged`, `resolved`, `reopened` . |
| `amount` | number | Amount on payment and credit notifications. |
| `transactionType` | string | How a payment was made, on payment notifications. |
| `isRead` | boolean | `true` once marked as read. |
| `createdAt` | string (date-time) | When it was written. |
| `updatedAt` | string (date-time) | When it last changed. |
| `user` | object | The person the notification was written for. Left out when that user no longer exists. |
| `user._id` | string | User id. |
| `user.firstName` | string | First name. |
| `user.lastName` | string | Last name. |
| `user.picture` | string | Profile picture URL, when set. |

</details>

Example response (Replies to your comments), `application/json`.

```json
{
  "status": "success",
  "data": {
"totalCount": 1,
"totalUnReadCount": 3,
"notificationList": [
  {
    "_id": "6702b1f0c3a4d5e6f7a8b9c1",
    "mediaId": "d8c2a1f4e5b6",
    "mediaType": "audio",
    "description": "Ana Reviewer replied to your comment on \"Customer call\"",
    "type": "comment",
    "action": "replied",
    "isRead": false,
    "createdAt": "2026-10-07T15:20:00.000Z",
    "updatedAt": "2026-10-07T15:20:00.000Z",
    "user": {
      "_id": "65f0c1a2b3c4d5e6f7a8b9c0",
      "firstName": "Alex",
      "lastName": "Lee"
    }
  }
]
  }
}
```

</div>

</ResponsePanel>

</div>

<h2 id="put-notification">Mark notifications as read</h2>

Marks every one of your own notifications as read, so `totalUnReadCount` drops to 0. It takes no body and does not touch anyone else's notifications.

<div slot="code">

<CodePanel label="Example request">

```bash
curl -X PUT 'https://api.speakai.co/v1/notification' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
```

</CodePanel>

<ResponsePanel id="put-notification" statuses={[{"code":"200","description":"Success"}]}>

<div slot="status-200">

**`200` Success**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | `success` on every 2xx response. One of: `success` . |
| `message` | string | Confirmation. |

Example response (Marked as read), `application/json`.

```json
{
  "status": "success",
  "message": "Notifications flag is updated successfully."
}
```

</div>

</ResponsePanel>

</div>

## Related pages

- [API reference](/api/) for the base URL, authentication, and the error format.
- [Authenticate with the Speak AI API using access tokens](/api/authentication/)
- [Upload audio and video to Speak AI and read insights](/api/media/)
- [Create and update live transcription sessions](/api/live-transcription/)
- [Analyze text notes with the Speak AI text endpoints](/api/text/)

Get an API key on the [Speak AI developer page](https://app.speakai.co/developers?utm_source=docs&utm_medium=referral&utm_campaign=api-reference&utm_content=api-notifications).

Source: https://docs.speakai.co/api/notifications/index.mdx
