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

# How to Use Pagination

> How cursor pagination works across the Financial Datasets API: results arrive in pages, each response links the next one, and a simple loop fetches everything you asked for.

List endpoints return results **in pages**. When your request matches more records than one page holds, the response includes a `next_page_url` — follow it to get the next page, and keep going until the field disappears.

## How it works

Request income statements with `limit=25`:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
curl "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25" \
  -H "X-API-KEY: your_api_key_here"
```

The response contains the first page of statements plus a link to the next page:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "income_statements": [ /* one page of records */ ],
  "next_page_url": "https://api.financialdatasets.ai/financials/income-statements?cursor=eyJhbGciOi..."
}
```

Request the `next_page_url` exactly as given — it is self-contained, no other parameters needed. The final page has **no** `next_page_url` field, which is your signal to stop.

## The loop

<CodeGroup>
  ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  import requests

  headers = {"X-API-KEY": "your_api_key_here"}

  url = "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25"

  statements = []
  while url:
      data = requests.get(url, headers=headers).json()
      statements.extend(data["income_statements"])
      url = data.get("next_page_url")

  print(f"fetched {len(statements)} statements")
  ```

  ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  const headers = { "X-API-KEY": "your_api_key_here" };

  let url =
    "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25";

  const statements = [];
  while (url) {
    const response = await fetch(url, { headers });
    const data = await response.json();
    statements.push(...data.income_statements);
    url = data.next_page_url;
  }

  console.log(`fetched ${statements.length} statements`);
  ```

  ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  URL="https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25"
  while [ -n "$URL" ]; do
    RESP=$(curl -s "$URL" -H "X-API-KEY: your_api_key_here")
    echo "$RESP" | jq '.income_statements | length'
    URL=$(echo "$RESP" | jq -r '.next_page_url // empty')
  done
  ```
</CodeGroup>

The same loop works on every list endpoint — only the array key changes (`prices`, `filings`, `insider_trades`, `news`, and so on).

## The cursor

`next_page_url` carries an opaque `cursor` token that encodes your original request — its filters, and where the last page ended.

* **Treat it as opaque.** Do not construct, modify, or store cursors long-term; get them from `next_page_url` only.
* **Other parameters are ignored alongside a cursor.** The cursor already carries your original filters, so filters cannot change mid-walk. To change filters, start a new request without a cursor.
* **Cursors are endpoint-specific.** A cursor from `/prices` will not work on `/filings`.

A modified or foreign cursor returns `400`:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "error": "Invalid cursor",
  "message": "The cursor is invalid, was issued for a different endpoint, or was modified. Re-issue the original request without a cursor to start over."
}
```

## Page size

Every page holds up to 10 records. Prices hold up to 100, sized for long histories of daily bars.

## What `limit` means

`limit` is the **total** number of records you want; pagination just delivers it across as many pages as needed. A request small enough to fit in a single page returns no `next_page_url` at all.

## Billing

Each page is a standard API request and is metered as one.

## Which endpoints paginate

All endpoints that return a list of records: financial statements (including segments and as-reported), financial metrics, prices, filings, earnings, news, KPIs, insider trades, insider ownership, beneficial and activist ownership, institutional holdings, index funds, and IPOs.

Endpoints that return a single object — company facts, snapshots, interest rates — and `/filings/items` (the sections of one filing) always return their full result.
