# Pagination

> Walk through long lists with a cursor.

List endpoints return a page of results and a cursor for the next page.

## Parameters

| Parameter | Type | What it does |
|---|---|---|
| `limit` | integer | Page size, 1 to 100. Defaults to 25. |
| `cursor` | string | The `next_cursor` from the previous response. Leave it out for the first page. |

## Response

```json
{
  "data": [ { "id": "8c1f0d52" }, { "id": "5d2e7a10" } ],
  "next_cursor": "WzE3OTQ...",
  "has_more": true
}
```

When `has_more` is `false` and `next_cursor` is `null`, you have reached the end.

Lists are newest first, by creation time, except articles, which are ordered by last update, and the messages of a conversation, which are oldest first. A malformed cursor starts again from the first page.

Treat a cursor as an opaque string. Do not build or edit one, and keep the same filters while you page. A few lists are not paged and always return every row with `next_cursor` set to `null`: help center collections, feedback boards and knowledge sources.

## Fetch everything

**JavaScript**

```js
async function* allConversations(status = 'open') {
  let cursor = null;
  do {
    const url = new URL('https://app.tirver.com/api/v1/conversations');
    url.searchParams.set('status', status);
    url.searchParams.set('limit', '100');
    if (cursor) url.searchParams.set('cursor', cursor);
    const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.TIRVER_API_KEY}` } });
    if (!res.ok) throw new Error(`Tirver ${res.status}`);
    const body = await res.json();
    yield* body.data;
    cursor = body.has_more ? body.next_cursor : null;
  } while (cursor);
}

for await (const conversation of allConversations()) console.log(conversation.id);
```

**Python**

```python
import os, requests

def all_conversations(status="open"):
    cursor = None
    while True:
        params = {"status": status, "limit": 100}
        if cursor:
            params["cursor"] = cursor
        res = requests.get(
            "https://app.tirver.com/api/v1/conversations",
            params=params,
            headers={"Authorization": f"Bearer {os.environ['TIRVER_API_KEY']}"},
            timeout=10,
        )
        res.raise_for_status()
        body = res.json()
        yield from body["data"]
        cursor = body["next_cursor"] if body["has_more"] else None
        if not cursor:
            break
```

Stay inside the [rate limits](https://tirver.com/help/api/rate-limits.md) when you page through a long list: use the largest page size that suits you instead of many small pages.

Source: https://tirver.com/help/api/pagination
