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

# Pagination

> Handling paginated results in the Bluerails API using cursor-based pagination.

export const PaginationWorkflowDiagram = () => {
  const RequestIcon = () => <svg width="20" height="20" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" className="flex-shrink-0 mr-2 text-blue-600 dark:text-blue-400">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M8 16v-4a4 4 0 0 1 8 0v4" />
      <path d="M10 16h4" />
      <path d="M3 12h1m8 -9v1m8 8h1m-15.318 6.682l.707 .707m12.707 -.707l-.707 .707" />
    </svg>;
  const ResponseIcon = () => <svg width="20" height="20" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" className="flex-shrink-0 mr-2 text-green-600 dark:text-green-400">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M3 12h1m8 -9v1m8 8h1m-15.318 6.682l.707 .707m12.707 -.707l-.707 .707" />
      <path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
      <path d="M15 12v6.5a2.5 2.5 0 0 0 5 0v-.5" />
      <path d="M9 12v6.5a2.5 2.5 0 0 1 -5 0v-.5" />
    </svg>;
  const LoopIcon = () => <svg width="20" height="20" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" className="flex-shrink-0 text-slate-500 dark:text-slate-400">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M4 12v-3a3 3 0 0 1 3 -3h10a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-3" />
      <path d="M7 9l-3 -3l3 -3" />
      <path d="M17 15l3 3l-3 3" />
    </svg>;
  const EndIcon = () => <svg width="20" height="20" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" className="flex-shrink-0 mr-2 text-red-600 dark:text-red-400">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
      <path d="M9 12l6 0" />
    </svg>;
  const ArrowDownIcon = () => <svg width="24" height="24" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" className="flex-shrink-0 text-slate-400 dark:text-slate-500">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M12 5l0 14" />
      <path d="M18 13l-6 6" />
      <path d="M6 13l6 6" />
    </svg>;
  return <div className="my-8 flex flex-col items-center justify-center gap-2 p-4">

      <div className="flex items-center p-3 border border-gray-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-lg shadow-sm w-full max-w-xs sm:max-w-sm">
        <RequestIcon />
        <span className="text-sm text-gray-700 dark:text-slate-200">
          Initial Request<span className="block text-xs text-gray-500 dark:text-slate-400">(No cursor, limit=50)</span>
        </span>
      </div>

      <div className="py-1">
        <ArrowDownIcon />
      </div>

      <div className="flex items-center p-3 border border-gray-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-lg shadow-sm w-full max-w-xs sm:max-w-sm">
        <ResponseIcon />
        <span className="text-sm text-gray-700 dark:text-slate-200">
          Server Response<span className="block text-xs text-gray-500 dark:text-slate-400">(Data + next_cursor="abc")</span>
        </span>
      </div>

      <div className="py-1">
        <ArrowDownIcon />
      </div>

      <div className="flex items-center p-3 border border-gray-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-lg shadow-sm w-full max-w-xs sm:max-w-sm">
        <RequestIcon />
        <span className="text-sm text-gray-700 dark:text-slate-200">
          Next Request<span className="block text-xs text-gray-500 dark:text-slate-400">(cursor="abc", limit=50)</span>
        </span>
      </div>

      <div className="py-1">
        <ArrowDownIcon />
      </div>

      <div className="flex items-center p-3 border border-gray-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-lg shadow-sm w-full max-w-xs sm:max-w-sm">
        <ResponseIcon />
        <span className="text-sm text-gray-700 dark:text-slate-200">
          Server Response<span className="block text-xs text-gray-500 dark:text-slate-400">(Data + next_cursor="xyz")</span>
        </span>
      </div>

      <div className="py-2 flex items-center text-slate-500 dark:text-slate-400">
        <LoopIcon />
        <span className="ml-2 text-xs italic">Repeat using latest next_cursor...</span>
      </div>

      <div className="flex items-center p-3 border border-gray-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-lg shadow-sm w-full max-w-xs sm:max-w-sm">
        <ResponseIcon />
        <span className="text-sm text-gray-700 dark:text-slate-200">
          Final Response<span className="block text-xs text-gray-500 dark:text-slate-400">(Data + next_cursor=null)</span>
        </span>
      </div>

      <div className="pt-2 flex items-center text-red-600 dark:text-red-400">
        <EndIcon />
        <span className="ml-2 text-xs font-medium">End of List</span>
      </div>

    </div>;
};

Most "list" endpoints in the Bluerails API (like listing accounts, payments, or payouts) return results in chunks, or "pages," rather than all at once. This prevents overly large responses and allows you to fetch data incrementally. We use **cursor-based pagination**.

## How Cursor Pagination Works

Instead of traditional page numbers, cursor pagination uses an opaque `cursor` string that points to a specific item in the dataset. To get the next page of results, you provide the `cursor` received from the previous response.

**Query Parameters:**

You control pagination using these query parameters on list endpoints:

* `limit` (optional, integer):
* Specifies the maximum number of items to return per page.
* Default: `25`
* Maximum: `100`
* `cursor` (optional, string):
* The cursor string obtained from the `next_cursor` field of the *previous* page's response.
* **Omit this parameter entirely for the very first request** to get the beginning of the list.

**Response Body:**

Paginated list endpoints return a JSON object with the following structure:

<CodeBlock language="json">
  ```json theme={null}
  {
    "data": [
    // ... array of resource objects (e.g., Accounts, Payments)
    ],
    "page_size": 25, // The actual number of items returned in this response
    "next_cursor": "aBcDeFgHiJkLmNoPqRsT..." // Cursor for the next page, or null/omitted if none
  }
  ```
</CodeBlock>

## Example Workflow: Listing Accounts

<PaginationWorkflowDiagram />

1. **Initial Request (Get the first page)**
   * Omit the `cursor` parameter.
   * *(See diagram: "Initial Request")*

2. **Server Response (First Page)**
   * The server returns the first 50 accounts and a `next_cursor`.
   * *(See diagram: "Server Response (Data + next\_cursor="abc")")*

3. **Next Request (Get the second page)**
   * Use the `next_cursor` value from the previous response as the `cursor` query parameter.
   * *(See diagram: "Next Request (cursor="abc", limit=50)")*

4. **Server Response (Second Page)**
   * The server returns the next 50 accounts and a new `next_cursor`.
   * *(See diagram: "Server Response (Data + next\_cursor="xyz")")*

5. **Repeat**
   * Continue making requests, using the latest `next_cursor` value each time.
   * *(See diagram: "Repeat using latest next\_cursor...")*

6. **Final Page**
   * Eventually, a response will have `next_cursor` as `null` or omitted, indicating there are no more pages.
   * *(See diagram: "Final Response (Data + next\_cursor=null)")*
