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

# Pagination

> Walk list endpoints with cursor-based pagination.

Every list endpoint returns the same envelope and uses cursor-based pagination. Cursors guarantee no duplicates or missing items even if data changes between requests. Items come back newest first, ordered by `created_at`.

## Request parameters

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| `limit`   | Page size, 1–100. Defaults to 10.                                            |
| `cursor`  | The `next_page` value from the previous response. Omit on the first request. |

## Response envelope

```json theme={null}
{
  "object": "list",
  "items": [
    /* … */
  ],
  "has_more": true,
  "next_page": "eyJsYXN0X2NyZWF0ZWRfYXQiOiIyMDI1LTAxLTE1VDEwOjMwOjAwLjAwMFoiLCJsYXN0X2lkIjoic3ViXzEyMzQ1Njc4OSIsImxpbWl0IjoyMH0="
}
```

| Field       | Description                                                       |
| ----------- | ----------------------------------------------------------------- |
| `items`     | The page of results.                                              |
| `has_more`  | `true` when more pages exist; `false` when this is the last page. |
| `next_page` | Opaque cursor for the next request, or `null` on the last page.   |

<Warning>
  Keep the same query parameters across the whole iteration (filters, `limit`,
  etc.). Changing them mid-walk invalidates the cursor.
</Warning>

## Walk a list

<Steps>
  <Step title="Fetch the first page">
    ```bash theme={null}
    curl "https://api.nomos.energy/customers?limit=20" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}"
    ```
  </Step>

  <Step title="Fetch each next page">
    Pass `next_page` from the previous response as `cursor` on the next request:

    ```bash theme={null}
    curl "https://api.nomos.energy/customers?limit=20&cursor=${NEXT_PAGE}" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}"
    ```
  </Step>

  <Step title="Stop when has_more is false">
    The last page returns `"has_more": false` and `"next_page": null`.
  </Step>
</Steps>

## Loop in code

```ts theme={null}
async function listAll<T>(path: string, token: string): Promise<T[]> {
  const items: T[] = [];
  let cursor: string | null = null;

  do {
    const url = new URL(path, "https://api.nomos.energy");
    if (cursor) url.searchParams.set("cursor", cursor);

    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${token}` },
    });
    const page = (await res.json()) as {
      items: T[];
      has_more: boolean;
      next_page: string | null;
    };

    items.push(...page.items);
    cursor = page.has_more ? page.next_page : null;
  } while (cursor);

  return items;
}
```

<Note>
  A malformed or tampered `cursor` returns `400 BAD_REQUEST`. See
  [Errors](/api-references/errors) for the full envelope.
</Note>
