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

# Pagination

> List endpoints return a fixed page size with an offset cursor. Follow nextOffset until it is null.

List endpoints return a page of results plus the offset of the next page.

## The envelope

```json theme={null}
{
  "data": [ /* … */ ],
  "limit": 10,
  "offset": 0,
  "nextOffset": 10
}
```

<ResponseField name="data" type="array" required>
  The results for this page, newest first.
</ResponseField>

<ResponseField name="limit" type="integer" required>
  Results per page. Fixed at **10** — it is not a request parameter.
</ResponseField>

<ResponseField name="offset" type="integer" required>
  The offset this page was fetched at.
</ResponseField>

<ResponseField name="nextOffset" type="integer | null">
  The offset to request next. **`null` means you have reached the end.**
</ResponseField>

## Paging through everything

Follow `nextOffset` until it is `null`. Do not compute offsets yourself.

```python theme={null}
import httpx

def all_payment_links(api_key, status=None):
    client = httpx.Client(
        base_url="https://api.moove.xyz",
        headers={"X-API-Key": api_key},
    )
    offset = 0
    while offset is not None:
        params = {"offset": offset}
        if status:
            params["status"] = status
        page = client.get("/v1/payment-link", params=params).raise_for_status().json()
        yield from page["data"]
        offset = page.get("nextOffset")
```

```typescript theme={null}
async function* allPaymentLinks(apiKey: string, status?: string) {
  let offset: number | null = 0;
  while (offset !== null) {
    const url = new URL('https://api.moove.xyz/v1/payment-link');
    url.searchParams.set('offset', String(offset));
    if (status) url.searchParams.set('status', status);

    const res = await fetch(url, { headers: { 'X-API-Key': apiKey } });
    if (!res.ok) throw new Error(`${res.status}`);

    const page = await res.json();
    yield* page.data;
    offset = page.nextOffset ?? null;
  }
}
```

<Warning>
  Stop on `nextOffset === null`, not on an empty `data` array. Treat `0` as a valid offset — a falsy check on `nextOffset` will terminate on the first page.
</Warning>

## Ordering and drift

Results come back **newest first**. New records are created at the front, so paging a busy account over a long period can shift items between pages.

<Tip>
  A `status` filter narrows the set but does not freeze it: links complete or expire while you page, and results are ordered by creation date, not by when their status changed. If one-pass completeness matters, de-duplicate on `id` and re-run the pass rather than trusting a single walk.
</Tip>

## Filtering

`GET /v1/payment-link` accepts a `status` filter of `active`, `inactive` or `completed`. Filtering server-side beats fetching everything and discarding most of it.

[Moove Payment Links →](/api-reference/moove-receive/moove-payment-links#list-payment-links)

## Next

<CardGroup cols={3}>
  <Card title="Moove Payment Links" icon="link" href="/api-reference/moove-receive/moove-payment-links">
    The list endpoint.
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/api-reference/rate-limits">
    Page politely.
  </Card>

  <Card title="Errors" icon="triangle-alert" href="/api-reference/errors">
    Handling failure mid-page.
  </Card>
</CardGroup>
