---
title: "List chat messages"
method: GET
path: "/chat/threads/{chatId}/messages"
tags: ["Chat"]
---

# List chat messages

`GET /chat/threads/{chatId}/messages`

## Request

- Base URL: `https://viral.app/api/v1`
- URL: `https://viral.app/api/v1/chat/threads/{chatId}/messages`
- Auth: API key in header `x-api-key`

Lists a conversation's messages with read receipts for both sides. Deleted messages are included as tombstones (`deletedAt` set, empty content).

- **History** (default): the newest `limit` messages, then older pages through `nextPageToken`; each page is in ascending order. The object `cursor` and `nextCursor` are the legacy form of the same paging.
- **Incremental sync** (`after`): the messages created at or after 2 minutes before `after`, oldest first. Pass `nextPageToken` back with the same `after` until it is null. Messages commit slightly out of order (a broadcast inserts many at once), so the window deliberately overlaps what you already hold: dedupe on message `id`. `createdAt` never changes on edits, so `after` does not return an edited or deleted message again: follow those through the `chat.message.updated` and `chat.message.deleted` webhooks.

A page token only continues the direction that issued it, and `cursor` cannot be combined with `pageToken` or `after` (400).

## Path parameters

- `chatId` string, required

## Query parameters

- `cursor` object: Legacy: the previous page's `nextCursor`. Prefer `pageToken`.
  - `createdAt` string, date-time, required
  - `id` string, required
- `pageToken` string: The previous page's `nextPageToken`. Pass it with the same `after`.
- `after` string, date-time: Incremental sync: the messages created at or after 2 minutes before this instant, oldest first.
- `limit` integer

## Response `200`

OK

- object
  - `messages` object[], required
    - `id` string, required
    - `chatId` string, required
    - `senderType` 'org' | 'creator' | 'system', required
    - `senderUserId` string, nullable, required
    - `senderDisplayName` string, nullable, required
    - `senderMember` object, nullable
      - `firstName` string, required
      - `image` string, nullable, required
    - `kind` string, required
    - `content` string, required
    - `metadata` object, nullable, required
    - `clientMessageId` string, required
    - `replyTo` object, nullable, required
      - `messageId` string, required
      - `senderType` 'org' | 'creator' | 'system', required
      - `senderUserId` string, nullable
      - `senderDisplayName` string, nullable, required
      - `senderMember` object, nullable
        - `firstName` string, required
        - `image` string, nullable, required
      - `contentPreview` string, required
      - `deleted` boolean, required
    - `reactions` object[], required
      - `emoji` string, required
      - `userId` string, required
      - `side` 'org' | 'creator', required
    - `attachments` object[], required
      - `id` string, required
      - `fileName` string, required
      - `mimeType` string, required
      - `sizeBytes` integer, required
      - `url` string, nullable, required
    - `createdAt` string, date-time, required
    - `editedAt` string, date-time, nullable, required
    - `deletedAt` string, date-time, nullable, required
    - `pinnedAt` string, date-time, nullable
    - `seenAt` string, date-time, nullable
    - `source` 'ui' | 'api' | 'copilot' | 'system', nullable
    - `language` string, nullable
  - `nextCursor` object, nullable, required
    - `createdAt` string, date-time, required
    - `id` string, required
  - `nextPageToken` string, nullable
  - `readState` object, required
    - `creatorLastReadAt` string, date-time, nullable, required
    - `orgLastReadAt` string, date-time, nullable, required
    - `memberReads` object[], nullable: Groups, for your organization only: when each creator member last read the conversation (members who never opened it are absent). A member has read every message created at or before their `lastReadAt`. Null in direct threads.
      - `userId` string, required
      - `lastReadAt` string, date-time, required
  - `viewerSide` 'org' | 'creator', required
  - `chatContext` object, required
    - `kind` 'direct' | 'group'
    - `orgName` string, required
    - `orgLogo` string, nullable, required
    - `creatorUserId` string, nullable, required
    - `creatorName` string, nullable, required
    - `creatorImage` string, nullable, required
    - `title` string, nullable
    - `publicTitle` string, nullable
    - `groupKind` 'manual' | 'campaign' | 'all', nullable
    - `campaignId` string, nullable
    - `memberCount` integer
    - `pendingMemberCount` integer, nullable
    - `campaignEnded` boolean, nullable
    - `members` object[], nullable
      - `userId` string, required
      - `name` string, required
      - `image` string, nullable, required
      - `orgCreatorId` string, nullable, required
      - `email` string, nullable, required
      - `reachable` boolean, required
      - `isMarketplaceCreator` boolean
    - `membersTruncated` boolean

## Other responses

- `400`: 400
- `401`: 401
- `402`: 402
- `404`: 404
- `408`: 408
- `429`: 429
- `500`: 500

---

[API](https://skmtc.dev/viral/apis/viral-app-api.md) · [All operations](https://skmtc.dev/viral/apis/viral-app-api/llms.txt) · [OpenAPI document](https://skmtc.dev/viral/apis/viral-app-api/revisions/31e97fa79ef1?raw)
