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

# Paginación

> Paginación con header Link RFC 5988 + X-Total-Count.

## Modelo

Los endpoints de lista en Rail devuelven un **array puro** (no envuelto en `{ data: [...] }`). La info de paginación va en headers:

| Header          | Significa                                               |
| --------------- | ------------------------------------------------------- |
| `X-Total-Count` | Total de resultados que matchean tu query.              |
| `Link`          | URLs a páginas siguientes/anteriores/última (RFC 5988). |

```bash theme={null}
curl -i "https://api.rail.cl/v1/accounts/acc_xxx/movements?per_page=10" \
  -H "Authorization: Bearer rail_sk_live_…"
```

Response headers:

```
HTTP/2 200
content-type: application/json
x-total-count: 238
link: <https://api.rail.cl/v1/accounts/acc_xxx/movements?per_page=10&page=2>; rel="next", <https://api.rail.cl/v1/accounts/acc_xxx/movements?per_page=10&page=24>; rel="last"
```

## Query params

| Param      | Default | Max   |
| ---------- | ------- | ----- |
| `page`     | `1`     | —     |
| `per_page` | `30`    | `300` |

## Parsear el header `Link`

```ts theme={null}
function parseLinkHeader(header: string): Record<string, string> {
  const links: Record<string, string> = {};
  for (const part of header.split(',')) {
    const m = part.trim().match(/^<(.+)>;\s*rel="(.+)"$/);
    if (m) links[m[2]] = m[1];
  }
  return links;
}

// Uso
const res = await fetch(url, { headers });
const links = parseLinkHeader(res.headers.get('link') ?? '');
console.log(links.next);  // → URL absoluta de la siguiente página
console.log(links.last);  // → URL absoluta de la última
```

## Iterar todo

```ts theme={null}
async function fetchAllMovements(accountId: string, apiKey: string) {
  const all: Movement[] = [];
  let url: string | null = `https://api.rail.cl/v1/accounts/${accountId}/movements?per_page=200`;
  while (url) {
    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });
    const page = await res.json();
    all.push(...page);
    const links = parseLinkHeader(res.headers.get('link') ?? '');
    url = links.next ?? null;
  }
  return all;
}
```

## Recomendación: usa `synced_since` en vez de `page`

Para sync incremental, **no paginees por `page`**. Usa `synced_since` con un cursor monótono:

```bash theme={null}
# Primer sync
curl "...?per_page=200&page=1"
# guarda el max(synced_at) de la response como cursor

# Sucesivos
curl "...?per_page=200&synced_since=<cursor>"
```

Esto te asegura que **no pierdes movs retroactivos** que el banco posteó días después de la transacción real. `page` puede saltearte movs si entre dos calls se insertaron nuevos en medio.
