> ## Documentation Index
> Fetch the complete documentation index at: https://developers.workchats.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Cursor pagination, the same on every list endpoint

`GET /v1/users`, `GET /v1/conversations`, and
`GET /v1/conversations/{conversation_id}/messages` share one pagination
style.

## Parameters

| Parameter | Default | Notes |
| - | - | - |
| `limit` | 200 | At most 1000. Values above 1000 are clamped, not rejected. |
| `cursor` | — | The previous page's `next_cursor`. Omit it for the first page. |

## Response

```json theme={null}
{
  "users": ["…"],
  "next_cursor": "opaque-string-or-null"
}
```

`next_cursor` is `null` on the last page. There's no way to jump to a
specific page or go backwards — walk forward until you get `null`.

## Cursors are opaque

Don't parse, store structure in, or construct a cursor yourself. Pass back
exactly what you were given. A malformed cursor (including one from a
different endpoint) returns `400 invalid_cursor` — it never silently resets
you to page one, so you won't quietly re-walk data you already have.

## A minimal loop

```javascript Node theme={null}
let cursor;
const conversations = [];

do {
  const url = new URL("https://public-api.workchats.com/v1/conversations");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.ACCESS_TOKEN}` },
  });
  const page = await res.json();
  conversations.push(...page.conversations);
  cursor = page.next_cursor;
} while (cursor);
```
