# Pagination

Paginated fields return a Relay-style **connection**. You request a page with `first` and `after`, and read `pageInfo` to know whether to fetch the next one. Every connection in the API shares this shape. This guide covers how to page through results; for the connection field tables, see the [Pagination reference](/api/v2/docs/types/pagination).

## The cursor loop

Pass `first` to set the page size. Read `pageInfo.hasNextPage` to decide whether to continue, and pass `pageInfo.endCursor` as the next request’s `after` value. Repeat until `hasNextPage` is `false`.

Select `nodes` to get the records directly, or `edges` when you need each node’s `cursor`. To get the size of the full result set, request `totalCount`.

> **totalCount on competitorBrands**
>
> [`competitorBrands`](/api/v2/docs/queries/competitor-brands) pins your own brand onto the first page as one extra node flagged `isOwnBrand`, and its `totalCount` counts tracked competitors only. On page one, that connection returns one more edge than `totalCount` reports. Every other connection matches `totalCount` exactly.

## Page-size bounds

`first` defaults to 20 and must be between 1 and 100. The exception is [`engagementHistory`](/api/v2/docs/queries/engagement-history), which accepts up to 1000 so you can fetch a single item’s full snapshot history in one page. Values outside the range are rejected with a GraphQL validation error rather than clamped: a request for `first: 500` fails instead of returning 100 results.

> **Request only what you need**
>
> The weighted rate-limit cost of a connection scales with the `first` value you request. Request the smallest page size that fits your use case, and let the cursor loop fetch more only when you need it. See the [Rate limits guide](/api/v2/docs/guides/rate-limits) for the cost model.

## Lists that are not connections

A few fields return a plain list rather than a cursor connection, because the result set is naturally small: a workspace’s saved views, its Collections, its custom-attribute schemas. They take no `first` and no `after`.

These lists are capped at 1000 rows. When a result is truncated, you get the first 1000 rows in the field’s own order, with no error and no other indication that more rows exist.

> **Don't treat a 1000-row response as complete**
>
> These fields are sized for workspaces with tens or hundreds of saved objects, not thousands. If one returns exactly 1000 rows, assume the result was truncated. There is no cursor to continue from; narrow the query instead, or contact support about the workspace.

The capped fields are `collections`, `contentViews`, `creatorViews`, `socialProfileViews`, `viewGroups`, `customAttributeSchemas`, and `filterPresets`. Each field’s reference page states the cap.

## Walkthrough

### Paginate items page by page

Fetch page one, then page two using the returned endCursor.

### Step 1

```graphql
query ItemsPaginationPage1($first: Int) {
  items(first: $first) {
    totalCount
    edges {
      node {
        id
        caption
        takenAt
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "first": 5
}
```

```http
Authorization: Bearer docs_demo_token_0000000000000000000000
WORKSPACE-ID: 6ccefa76-e8ba-5ab0-9c60-e48a9e235a4a
```

```json
{
  "data": {
    "items": {
      "totalCount": 30,
      "edges": [
        {
          "node": {
            "id": "452a119f-393e-5edf-a7f7-f563294f3885",
            "caption": "Reel #29 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-30T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "d8a538a5-8857-5c0c-b3fb-a2b83c8d2a0b",
            "caption": "Post #28 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-29T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "330cce49-6139-5672-9c61-33fb35bc73e2",
            "caption": "Short #27 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-28T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "a61d036b-fe79-538c-bbbb-1f97162cab3c",
            "caption": "Story #26 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-27T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "de1860a7-2d98-5eda-8977-116583725c74",
            "caption": "Reel #25 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-26T00:00:00Z"
          }
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "Z2lkOi8vYXJjaGl2ZS9JdGVtL2RlMTg2MGE3LTJkOTgtNWVkYS04OTc3LTExNjU4MzcyNWM3NA=="
      }
    }
  }
}
```

### Step 2

```graphql
query ItemsPaginationPage2($first: Int, $after: String) {
  items(first: $first, after: $after) {
    edges {
      node {
        id
        caption
        takenAt
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```json
{
  "first": 5,
  "after": "Z2lkOi8vYXJjaGl2ZS9JdGVtL2RlMTg2MGE3LTJkOTgtNWVkYS04OTc3LTExNjU4MzcyNWM3NA=="
}
```

```http
Authorization: Bearer docs_demo_token_0000000000000000000000
WORKSPACE-ID: 6ccefa76-e8ba-5ab0-9c60-e48a9e235a4a
```

```json
{
  "data": {
    "items": {
      "edges": [
        {
          "node": {
            "id": "3870b3f7-2066-56c1-b82e-f7c606c863fa",
            "caption": "Post #24 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-25T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "2adb5caf-5619-5fc5-b738-ba264cb394a7",
            "caption": "Short #23 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-24T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "5b570218-bf6a-5e05-9389-2f9bfe7f73ce",
            "caption": "Story #22 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-23T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "24bd35e7-4ae8-546b-bc76-b9cee5e1107f",
            "caption": "Reel #21 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-22T00:00:00Z"
          }
        },
        {
          "node": {
            "id": "5503f877-fd11-5373-b372-ce4738980780",
            "caption": "Post #20 from Northwind Botanicals #northwindbotanicals #plantcare #growwithnorthwind @northwindbotanicals",
            "takenAt": "2024-11-21T00:00:00Z"
          }
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "Z2lkOi8vYXJjaGl2ZS9JdGVtLzU1MDNmODc3LWZkMTEtNTM3My1iMzcyLWNlNDczODk4MDc4MA=="
      }
    }
  }
}
```

For the connection and `PageInfo` field tables, see the [Pagination reference](/api/v2/docs/types/pagination).
