# List chats

`GET /chat.list`

## Description

List accessible chats — DMs, multi-DMs, group chats, all-hands "team
Roam" groups, and meeting chats.

**Personal access tokens** are backed by the user's inbox: chats are
ordered by most recent activity and include `lastMessageTime`,
`isUnread`, `preview`, `isMuted`, and `isPinned`. Bot threads (where
the user has unread replies) are returned as separate rows keyed by
`threadTimestamp`.

**Organization tokens** receive the chats the bot has access to,
ordered by chat creation time. Inbox-derived fields
(`lastMessageTime`, `isUnread`, `preview`, `isMuted`, `isPinned`) are
not populated, since bot addresses do not accumulate inbox state for
normal messages — those are delivered via webhooks.

Timestamps are returned in the caller's timezone (see
[Timezone handling](/docs/guides/migration-v0-to-v1#timezone-handling)).

**Required scope:** `chat:read`

Pass `expand=addresses` to include an address sidecar for chat participants
and preview senders. See [Identity & Principals](/docs/guides/identity-and-principals).

---

**OpenAPI Spec:** [chat-v1.json](https://developer.ro.am/chat-v1.json)

## Authentication

```
Authorization: Bearer YOUR_API_KEY
```

## Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `limit` | query | integer | No | Number of chats to return per response. Default 10, max 50. |
| `cursor` | query | string | No | Opaque pagination cursor from a previous response's `nextCursor`. Do not construct cursors manually. |
| `expand` | query | string | No | Comma-separated fields to expand. Supported: `addresses` — include an `addresses` map resolving chat participants and preview sender IDs.  |

## Responses

### 200 - Chats retrieved successfully

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `chats` | object[] | No |  |
| `nextCursor` | string | No | Pagination cursor for fetching the next page of results. |
| `addresses` | object | No | Resolved addresses keyed by UUID. Included only with `expand=addresses`. |

**chats** (array item):

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | string | Yes | The Chat ID. |
| `type` | "dm" | "group" | No | The kind of chat, using the same vocabulary as the `chat.message` webhook `chatType` filter: `dm` for direct and multi-person DMs, `group` for group chats (including all-hands and meeting channels). O |
| `threadTimestamp` | integer | No | Unix-microsecond timestamp of the parent message when this row represents a thread (Personal tokens only). Absent for top-level chat rows.  |
| `name` | string | Yes | Descriptive name for the chat:  * Group chat — the group name * DM — the name of the other party * Multi-DM — comma-separated list of participant names  |
| `groupId` | string | No | The Group ID. Only present for group chats (including all-hands and meeting chats); absent for DMs and Multi-DMs.  |
| `created` | string | Yes | When the chat was created (RFC3339, caller's timezone). |
| `lastMessageTime` | string | No | Time of the most recent activity. Personal access only; absent on Organization responses.  |
| `isUnread` | boolean | No | `true` if the chat has unread messages. Personal access only.  |
| `preview` | object | No | Preview of the most recent message. Personal access only.  |
| `isMuted` | boolean | No | `true` if the user has muted the chat. Personal access only.  |
| `isPinned` | boolean | No | `true` if the user has pinned the chat. Personal access only.  |

**preview**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `text` | string | No |  |
| `contentType` | "text" | "voice" | "poll" | No |  |
| `senderId` | string | No | User ID of the message sender. Present when the previewed message has a principal author; system previews (such as membership changes) and deleted messages omit it. When present, it resolves through ` |
| `sender` | object | No | Per-message sender display override the previewed message was sent with. Present only when the message carries one; `senderId` remains the authoring identity. Omitted for deleted messages. See the [Se |
| `mentioned` | boolean | No | `true` if the previewed message mentions the user. |


#### Example Response

```json
{
  "chats": [
    {
      "id": "295155ae-7df5-4ed5-9ebc-89a170559c81",
      "type": "group",
      "name": "Engineering Team",
      "groupId": "88bebce7-6cbb-4666-96f9-5c02d73e6661",
      "created": "2025-12-13T05:07:54-08:00",
      "lastMessageTime": "2026-04-18T09:14:02-07:00",
      "isUnread": true,
      "preview": {
        "text": "Let's review the Q2 roadmap on Friday.",
        "contentType": "text",
        "senderId": "ad1e9cc0-0ffd-47e5-895c-2630a73327b4",
        "mentioned": true
      }
    },
    {
      "id": "53b8a72b-b442-4da2-94ea-41b6116c14ea",
      "type": "dm",
      "name": "Alex Chen",
      "created": "2025-10-18T23:29:25-07:00",
      "lastMessageTime": "2026-04-17T16:02:11-07:00",
      "isPinned": true
    }
  ],
  "nextCursor": "YzE6MTc2MDgzMDE2NTEwNTAwMA"
}
```

### 400 - Bad request. Common causes:
- `limit` is non-numeric, ≤ 0, or > 50
- `cursor` is not a valid micro-second timestamp


### 401 - Presented invalid authentication credentials.

### 405 - An unsupported method was requested.

### 500 - An internal error occurred, including a preview sender that cannot resolve as a visible principal. The endpoint does not return a partial page.

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/api/chat-list*
