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

# Using pagination in the GraphQL API

> Learn how to paginate through large result sets in the Pylon GraphQL API

The Pylon GraphQL API uses cursor-based pagination for collections. This guide shows you how to page through results using the connection pattern.

## Understanding connections

Connections are collections that support pagination. They follow a consistent structure:

```graphql theme={null}
query {
  deals(first: 10) {
    edges {
      node {
        id
        friendlyId
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}
```

## Connection fields

* `edges`: An array of edge objects, each containing a `node` and a `cursor`
* `node`: The actual data object
* `pageInfo`: Information about the current page and available pages
  * `hasNextPage`: Boolean indicating if more pages are available
  * `hasPreviousPage`: Boolean indicating if previous pages exist
  * `startCursor`: Cursor for the first item in the current page
  * `endCursor`: Cursor for the last item in the current page

## Forward pagination

Use `first` and `after` to page forward:

```graphql theme={null}
query GetDeals($first: Int, $after: String) {
  deals(first: $first, after: $after) {
    edges {
      node {
        id
        friendlyId
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

**Variables for first page:**

```json theme={null}
{
  "first": 10
}
```

**Variables for next page:**

```json theme={null}
{
  "first": 10,
  "after": "eyJpZCI6IjEyMyJ9"
}
```

## Backward pagination

Use `last` and `before` to page backward:

```graphql theme={null}
query GetDeals($last: Int, $before: String) {
  deals(last: $last, before: $before) {
    edges {
      node {
        id
        friendlyId
      }
      cursor
    }
    pageInfo {
      hasPreviousPage
      startCursor
    }
  }
}
```

## Pagination limits

* `first` and `last` must be between 1 and 500
* You must specify either `first` or `last`, but not both
* If you specify `first`, you can optionally include `after`
* If you specify `last`, you can optionally include `before`

## Example: paginating through all deals

```javascript theme={null}
async function getAllDeals(accessToken) {
  let allDeals = [];
  let hasNextPage = true;
  let cursor = null;

  while (hasNextPage) {
    const query = `
      query GetDeals($first: Int, $after: String) {
        deals(first: $first, after: $after) {
          edges {
            node {
              id
              friendlyId
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    `;

    const variables = {
      first: 100,
      ...(cursor && { after: cursor })
    };

    const response = await fetch('https://pylon.mortgage/graphql', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ query, variables })
    });

    const result = await response.json();
    const deals = result.data.deals;

    allDeals = allDeals.concat(deals.edges.map(edge => edge.node));
    hasNextPage = deals.pageInfo.hasNextPage;
    cursor = deals.pageInfo.endCursor;
  }

  return allDeals;
}
```

## Sorting with pagination

You can combine pagination with a sort direction:

```graphql theme={null}
query GetDeals($first: Int, $after: String, $sortDirection: SortDirection) {
  deals(first: $first, after: $after, sortDirection: $sortDirection) {
    edges {
      node {
        id
        friendlyId
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Best practices

1. **Use appropriate page sizes** - Don't request more than you need, but avoid too many small requests
2. **Store cursors** - Save `endCursor` to resume pagination later
3. **Handle empty results** - Check if `edges` is empty
4. **Respect rate limits** - Don't make excessive pagination requests
5. **Use `hasNextPage`** - Check this before making another request

## Common patterns

### Fetching a specific page

If you need to jump to a specific page, you'll need to paginate from the beginning or store cursors:

```javascript theme={null}
async function getPage(accessToken, pageNumber, pageSize = 10) {
  let currentPage = 0;
  let cursor = null;

  while (currentPage < pageNumber) {
    const result = await fetchPage(accessToken, pageSize, cursor);
    cursor = result.pageInfo.endCursor;
    currentPage++;
  }

  return result;
}
```

### Counting total items

The connection pattern doesn't provide a total count. If you need a count, you'll need to paginate through all items or use a separate query if available.
