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

# Pagination

> [!NOTE]
>
> Spot collections are available on Mainnet and Testnet. Perpetual, Lending, Margin Trading, and Vault collections are **Testnet-Only**.

Paged endpoints return the same array or object on every page. Read the continuation from response headers:

```http theme={null}
X-Next-Cursor: <opaque token>
Link: <https://host/api/v1/...?cursor=...>; rel="next"
```

Pass the token unchanged as `cursor`, keeping all filters unchanged. A malformed token or a token for another filter set returns `400 BAD_REQUEST`. `limit` may change between pages. Stop when `X-Next-Cursor` is absent, not when a page is shorter than `limit`. Browser clients can read these headers through CORS.

| Collection | Default / maximum `limit` | Direction |
| - | - | - |
| Spot trades, user fills, orders | 100 / 500 | Newest first |
| Perp trades, orders, fills, funding history/payments, ledger, closeouts | 100 / 500 | Newest first |
| Spot OHLCV, Perp candles | 500 / 1,000 | Bars returned oldest first; see below |
| Lending liquidations, Margin activity/liquidations | 100 / 500 | Newest first |
| Vault directory, user vaults | 100 / 500 | Vault address ascending |
| Vault activity, redemptions | 100 / 500 | Newest origin event first |

Oversized page limits are capped. Orderbook depth is a separate parameter and rejects values over 20. Bounded reference lists, including markets, currencies and tickers, are not paged.

## Example: walk a Perp fill history (Testnet-Only)

Set `API_URL` to `https://test-dex-api.cloud.aultblockchain.xyz` and `OWNER` to a valid wallet address. This read-only example uses Python's standard library and retains decimal strings.

```python theme={null}
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen

base = os.environ["API_URL"].rstrip("/")
owner = os.environ["OWNER"]
params = {"limit": 100}
seen = set()
for _ in range(100):  # Bound memory and request work in production.
    url = f"{base}/api/v1/perp/owners/{owner}/fills?{urlencode(params)}"
    with urlopen(Request(url, headers={"User-Agent": "ault-mm-example/1.0"})) as res:
        rows = json.load(res)
        cursor = res.headers.get("X-Next-Cursor")
    for row in rows:
        print(row["id"], row["quantity"], row["feeDenom"], row["fee"])
    if not cursor:
        break
    if cursor in seen:
        raise RuntimeError("Repeated pagination cursor")
    seen.add(cursor)
    params["cursor"] = cursor
```

## Time windows and changing state

Perp feeds use inclusive `from` and `to` in Unix milliseconds. Spot feeds use `since`. Candles return ascending bars: without `since` (Spot) or `from` (Perp), start at the newest page and page backward; with the lower bound, start there and page forward. Keep the lower bound unchanged when passing the cursor.

A cursor marks a position in the list, not a frozen copy of the data. Orders and vaults can change between requests, so re-read the newest page after you finish paging.

Spot trades, user fills, Lending liquidations and Margin feeds also accept legacy `before_height` plus `before_index`. Supply both together. Prefer the opaque cursor. Spot trade cursor requests can return 503 while ordering checks are pending or historical event keys need repair.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.