# Pagination & Filtering

> Navigate large result sets with cursor-based pagination, filter by status or date, and sort results from the watsi API.

Source: https://docs.watsi.ai/en/guides/pagination

List endpoints in the watsi API use cursor-based pagination to deliver large result sets efficiently. This guide explains how to paginate, filter, and sort API responses.

## Cursor-based pagination

Every list endpoint returns a JSON object with the resource array and a `hasMore` boolean. When `hasMore` is `true`, additional pages are available.

```http
GET /api/v1/conversations?limit=20

{
  "chats": [ ... ],
  "hasMore": true
}
```

To fetch the next page, pass the `before` parameter with the ISO 8601 timestamp of the last item's `created_at` or `last_message_at` field:

```http
GET /api/v1/conversations?limit=20&before=2025-03-15T10:30:00.000Z
```

## Pagination parameters

- `limit` (integer)
  Number of items per page. Default: 20. Maximum: 100.

- `before` (string)
  ISO 8601 datetime cursor. Returns items created before this timestamp.

## Paginating through all results

Example: fetch all conversations page by page.

```javascript
async function fetchAllConversations(apiKey) {
  let before = undefined
  const all = []

  while (true) {
    const url = new URL('https://api.watsi.ai/api/v1/conversations')
    url.searchParams.set('limit', '100')
    if (before) url.searchParams.set('before', before)

    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}` },
    })
    const data = await res.json()

    all.push(...data.chats)

    if (!data.hasMore) break
    before = data.chats.at(-1).last_message_at
  }

  return all
}
```

## Filtering

Some list endpoints accept query parameters to narrow results. The available filters depend on the resource type.

| Endpoint                    | Filter parameters                      |
| --------------------------- | -------------------------------------- |
| `GET /api/v1/conversations` | `status`, `assigned_user_id`           |
| `GET /api/v1/customers`     | `search` (name or phone), `tag_id`     |
| `GET /api/v1/templates`     | `status` (approved, pending, rejected) |

Example: fetch only open conversations:

```http
GET /api/v1/conversations?status=open&limit=20
```

## Sorting

List endpoints return results sorted by **most recent first** (descending by timestamp). This default sort order is consistent across all resources and cannot be changed via query parameters.

> **Note**

The cursor-based pagination model relies on this sort order — the `before` parameter always moves backward in time.

## Response envelope

Each resource type uses a predictable key in the response object:

| Endpoint                | Response key |
| ----------------------- | ------------ |
| `/api/v1/conversations` | `chats`      |
| `/api/v1/customers`     | `customers`  |
| `/api/v1/templates`     | `templates`  |
| `/api/v1/tags`          | `tags`       |
| `/api/v1/users`         | `users`      |

All list responses also include `hasMore: boolean` at the top level.
