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

# Pagination

> Learn how to iterate through a collection's pages.

<RequestExample>
  ```http Request theme={null}
  GET /lucca-api/employees?include=totalCount,links&limit=25 HTTPS/1.1
  Host: example.ilucca.net
  Authorization: Bearer <ACCESS_TOKEN>
  Api-Version: <API_VERSION>
  Accept: application/json
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "url": "https://example.ilucca.net/lucca-api/employees",
    "type": "employees",
    "items": [],
    "totalCount": 2127,
    "links": {
      "prev": {
        "href": "https://example.ilucca.net/lucca-api/employees?include=totalCount,links&limit=25&page=!8e7"
      },
      "next": {
        "href": "https://example.ilucca.net/lucca-api/employees?include=totalCount,links&limit=25&page=!S7DHF"
      }
    }
  }
  ```
</ResponseExample>

All collection endpoints are subject to pagination. This means you most likely won't be able to retrieve all resources in a single HTTP request. Paging is enforced in order to enhance response times and lower error rates.

<Tip>The Lucca API implements a **cursor-based pagination**, which is blazing fast and prevents you from having to deal with duplicated or skipped results when paging over changing data (or due to inconsistent sorting). It's the **recommended way** of paging.</Tip>

You can control paging through two query parameters:

<CardGroup cols={2}>
  <Card title="Page Size">
    Page size is negotiated through the `(int) limit` (min is zero, max may depend on API endpoint), and as a result dictates the maximum number of items per page the server will respond with.
  </Card>

  <Card title="Page Cursor">
    `(string) page` is the continuation token (i.e. cursor) obtained during a previous request allowing you to retrieve the next page or the previous page.

    You may also provide a number as `(int) page` (starting at page `1`) if you really need indexed pages, but this is not recommended.
  </Card>
</CardGroup>

<Warning>The Lucca API enforces a maximum value to the `limit` parameter, which varies by endpoint (typically 100 or 1,000), as well as a default value if none is given. Please refer to the [Lucca API Reference](/api-reference/latest) for the given collection endpoint.</Warning>

Paginated responses have:

* `items` contains the resources in the given page;
* `totalCount` indicates how many resources exist across all pages (while applying the query filters) - the server will only return this count when requesting it through `?include=totalCount`;
* `links` contains both the links to the previous and the next pages (`null` if there is none) - the server will only return this count when requesting it through `?include=links`.

<Warning>Both the `totalCount` and `links` properties are only returned if your HTTP request explicitly includes them: `?include=totalCount,links`.</Warning>

<Tip>Paginated requests should be sorted explicitly. By default, most API endpoints fall back to an "ascending `id`" sorting when the `?sort` query parameter is omitted.</Tip>

As a result, retrieving all pages may look something like this:

<CodeGroup>
  ```js app.js theme={null}
  import merge from 'my-deepmerge-algorithm';

  // Retrieve all pages from a Lucca API collection  
  async function getAllPages(apiUrl, accessToken) {
    let allItems = {items: [], embedded: {}};

    // Recursive page fetch
    const fetchPage = async (url) => {
      const response = await fetch(url, {
        headers: {
          'Authorization': `Bearer ${accessToken}`
        }
      });

      if (!response.ok) {
        throw new Error(`Failed to fetch page: ${response.status} ${response.statusText}`);
      }

      const data = await response.json();
      const items = data.items || [];
      const embedded = data.embedded || {};

      allItems.items = allItems.items.concat(items);
      // Merge embedded resources with your favorite deep-merge util.
      // As a reminder, embedded is a dictionary of resource-types whose values are themselves a dictionary of resource representations
      // indexed by their id. E.g.: { "embedded": { "resourceType": { "ID1": { ... } } } }
      allItems.embedded = merge(allItems.embedded, embedded);

      // Check if there's a next page
      // Alternative: you could also predict how many pages there are from the totalCount property value,
      // then go for a for loop.
      const nextPageUrl = data.links && data.links.next && data.links.next.href;

      if (!!nextPageUrl) {
        // Fetch the next page
        await fetchPage(nextPageUrl);
      }
    };

    // Start fetching from the initial API URL
    await fetchPage(apiUrl);

    return allItems;
  }

  // Example usage
  const apiUrl = 'https://example.ilucca-sandbox.net/lucca-api/employees?include=totalCount,embedded,links';
  const accessToken = 'your_oauth_access_token';

  getAllPages(apiUrl, accessToken)
  .then((allItems) => {
    console.log('All items:', allItems);
  })
  .catch((error) => {
    console.error('Error:', error.message);
  });
  ```
</CodeGroup>

<br />

<CardGroup cols="1">
  <Card title="About includes" href="./includes">
    Learn more about how to include links and/or related resources.
  </Card>

  <Card title="Sorting results" href="./sorting">
    Learn more about how to sort the items of a collection.
  </Card>
</CardGroup>
