---
title: "Pagination"
method: GET
path: "/guides/pagination"
tags: ["Pagination"]
---

# Pagination

`GET /guides/pagination`

## Request

- Base URL: `https://developers.chatway.app/api/v1`
- URL: `https://developers.chatway.app/api/v1/guides/pagination`
- Auth: none required

# Pagination

List endpoints use **offset pagination** with `page` and `limit` query parameters. Chatway does **not** use cursor-based pagination (`cursor`, `next_cursor`, or `has_more`).

## Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `page` | integer | `1` | Page number (1-based). Must be at least `1`. |
| `limit` | integer | varies | Number of records per page. Must be at least `1`. Maximum depends on the endpoint (see below). |

Example: request page 2 of a workspace with 3 contacts, 2 per page, returning only `name` and `email`:

```bash
curl -G "https://developers.chatway.app/api/v1/contacts" \
  -H "X-API-KEY: your_api_key" \
  --data-urlencode "page=2" \
  --data-urlencode "limit=2" \
  --data-urlencode "include_fields=name,email"
```

## Response shape

Paginated responses include `data`, `meta.pagination`, and `links`. Page 2 is the last page here, so it holds the remaining contact and `links.next` is `null`:

```json
{
  "data": [
    {
      "type": "chat-contacts",
      "id": "9b0c5fe6-35ad-459d-b6ba-4288191f84f1",
      "attributes": {
        "name": "Jane Doe",
        "email": "jane@example.com"
      }
    }
  ],
  "meta": {
    "pagination": {
      "total": 3,
      "count": 1,
      "per_page": 2,
      "current_page": 2,
      "total_pages": 2
    }
  },
  "links": {
    "self": "https://developers.chatway.app/api/v1/contacts?page=2",
    "first": "https://developers.chatway.app/api/v1/contacts?page=1",
    "next": null,
    "last": "https://developers.chatway.app/api/v1/contacts?page=2"
  }
}
```

| Field | Description |
|---|---|
| `meta.pagination.total` | Total records across all pages |
| `meta.pagination.count` | Records returned on this page |
| `meta.pagination.per_page` | Page size used for this response (matches `limit`) |
| `meta.pagination.current_page` | Current page number |
| `meta.pagination.total_pages` | Total number of pages |
| `links.next` | URL for the next page, or `null` on the last page |
| `links.first` / `links.last` | First and last page URLs |

Follow `links.next` until it is `null`, or increment `page` until `current_page >= total_pages`.

Pagination links contain only the `page` parameter. When following a pagination link, preserve the `limit`, `include_fields` and `exclude_fields` values from your original request if they are not included in that link.

## Defaults and limits by endpoint

| Endpoint | Default `limit` | Maximum `limit` |
|---|---|---|
| `GET /contacts` | `10` | `100` |
| `GET /conversations/all` | `10` | `100` |
| `GET /conversations/{id}/messages` | `20` | `20` |
| `GET /widgets` | `20` | `100` |
| `GET /agents` | `20` | `100` |

Sending `limit` above the maximum returns **422** with an validation error.

## Sort order

| Endpoint | Order |
|---|---|
| `GET /conversations/all` | Open conversations first, then by most recent message activity (newest first) |
| `GET /conversations/{id}/messages` | Newest messages first (`sort_number` descending) |
| `GET /contacts` | Platform default contact ordering for your workspace |
| `GET /widgets` | Platform default widget ordering |
| `GET /agents` | Platform default agent ordering |

Sort order is not configurable through query parameters on these endpoints.

## Live data and page drift

Each page reflects the data when that request runs. A sequence of page requests is not one fixed snapshot. New messages can move conversations between pages, so a long-running scan can encounter a record more than once or miss a record that moved.

- **Conversation lists** can change order when new messages arrive, because ordering uses latest activity.
- **Message lists** can gain new rows while you paginate; a new visitor or agent message may appear on page 1 after you already fetched page 2.

For near-real-time workflows, prefer **webhooks** (`message.received`) instead of polling message or conversation lists on a short interval.

When importing several pages, track records by their IDs rather than their position in the list. Keep the same page size and filters throughout the scan. Use webhooks for ongoing changes instead of repeatedly scanning the full history.

## Field filtering

**List Chat Contacts**, **List Conversations** and **List Conversation Messages** support `include_fields` and `exclude_fields`. Supply comma-separated attribute names from that operation's allowed list. For example, `include_fields=name,email` requests those contact attributes. If both parameters are present, `include_fields` takes precedence. Invalid field names return **422**. **List Agents** and **List Widgets** do not document field filtering.

## Related pages

- **Overview**: authentication and resource summary
- **Errors**: validation and rate-limit responses
- **Rate limits**: request quotas per API key

## Response `200`

Documentation.

---

[API](https://skmtc.dev/chatway/apis/chatway-developer-docs.md) · [All operations](https://skmtc.dev/chatway/apis/chatway-developer-docs/llms.txt) · [OpenAPI document](https://skmtc.dev/chatway/apis/chatway-developer-docs/revisions/ca1a1da291cc?raw)
