# Public API pagination

Every list operation answers with the same envelope: the page's items in `data`, and links to the neighbouring pages in `links`. Cost data adds what the whole query covers in `meta`.

## Read a list page by page

<Stepper>

1. Request the first page with `page=1` and the `limit` you want.
2. Process `data`.
3. When `links.next` is set, request that link; it keeps every filter of the first request. When it is `null`, that was the last page.

</Stepper>

```bash
curl --get https://api.costfluent.com/v1/budgets \
  --data page=1 --data limit=100 \
  --header "Authorization: Bearer $COSTFLUENT_API_TOKEN"
```

```json
{
  "links": {
    "self": "https://api.costfluent.com/v1/budgets?page=1&limit=100",
    "first": "https://api.costfluent.com/v1/budgets?page=1&limit=100",
    "prev": null,
    "next": "https://api.costfluent.com/v1/budgets?page=2&limit=100",
    "last": "https://api.costfluent.com/v1/budgets?page=3&limit=100"
  },
  "data": []
}
```

## Page size

| Operation | `limit` | Default |
|---|---|---|
| Every list, such as budgets, cost reports or integrations | 1 to 100; a larger or smaller value is held to that range | 20 |
| Cost data, `GET /v1/costs` | 1 to 5,000; a larger value is refused with `400` | 20 |

## Reading cost data in bulk

Cost data is the one bulk read: ask for `limit=5000` to read a window in as few requests as possible. Paging reaches 100,000 rows, `page × limit`; a request past that is refused with `400`, and its error says to split the date window. Read a large window as several shorter `startDate` to `endDate` ranges, each from page 1.

:::note
`meta.totalRecords` counts every row the query matches, so `meta.totalRecords` divided by `limit` tells you how many pages to expect before you start.
:::

## How it behaves

- `page` starts at 1. A page past the end answers `200` with an empty `data`.
- `links.last` is `null` when the total is not known.

## Related

- [Rate limits](/api/rate-limits)
- [Errors](/api/errors)
- [API reference](/api)
