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

# Pagination

> Navigate through large result sets with cursor-based pagination

All list endpoints return paginated results using cursor-based pagination.

## Basic usage

Control the number of results per page with the `limit` parameter (1–100, default 10):

```bash theme={null}
curl "https://api.altahq.com/v1/campaigns?limit=25" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

## Response format

Every list endpoint returns a response with pagination metadata:

```json theme={null}
{
  "data": [...],
  "hasMore": true,
  "next": "eyJ2IjoxLCJ0IjoicGFnZS1iYXN..."
}
```

| Field      | Type      | Description                                    |
| ---------- | --------- | ---------------------------------------------- |
| `data`     | `array`   | The list of objects for the current page       |
| `hasMore`  | `boolean` | Whether there are more results after this page |
| `next`     | `string`  | Cursor to fetch the next page                  |
| `previous` | `string`  | Cursor to fetch the previous page              |

## Fetching the next page

Pass the `next` value as `cursor` to fetch the next page:

```bash theme={null}
curl "https://api.altahq.com/v1/campaigns?cursor=eyJ2IjoxLCJ0IjoicGFnZS1iYXN..." \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

<Warning>
  Cursors are tied to the original query filters. You cannot change filters
  between pages - doing so returns an error.
</Warning>

## Example: iterating through all results

```typescript theme={null}
const API_URL = "https://api.altahq.com/v1/campaigns";
const headers = { Authorization: "Bearer YOUR_API_TOKEN" };

async function fetchAllCampaigns() {
  const allCampaigns = [];
  let params = new URLSearchParams({ limit: "50" });

  while (true) {
    const response = await fetch(`${API_URL}?${params}`, { headers });
    const { data, hasMore, next } = await response.json();
    allCampaigns.push(...data);

    if (!hasMore) break;

    params = new URLSearchParams({ cursor: next });
  }

  console.log(`Fetched ${allCampaigns.length} campaigns`);
  return allCampaigns;
}
```
