# Paginación

> Paginación por cursor en la API de Simplo — Page<T>, auto-paginación con for await y checkpoints manuales de cursor.

Los endpoints de listado usan **paginación por cursor**: cada página trae un
`next_cursor` opaco que devuelves para obtener la página siguiente.

## Con la API REST

Esto es lo que devuelve la API de verdad. `limit` va de 1 a 100 (default 20).

```bash
curl "https://api.simplo.cl/api/v1/billing/dte?limit=2" \
  -H "X-Api-Key: $SIMPLO_API_KEY"
```

```json
{
  "items": [
    {
      "id": "4f9c9c2e-8a49-4f2e-9d5f-0d8f3a1b2c3d",
      "tipo_dte": 33,
      "folio": 1042,
      "estado": "aceptado",
      "rut_receptor": "76543210-3",
      "razon_social_receptor": "Cliente Ejemplo SpA",
      "fecha_emision": "2026-09-04",
      "monto_total": 595000,
      "created_at": "2026-09-04T14:30:00Z",
      "updated_at": "2026-09-04T14:30:12Z"
    }
  ],
  "next_cursor": "eyJvIjoxNzU3..."
}
```

Para la página siguiente, devuelve el cursor tal cual:

```bash
curl "https://api.simplo.cl/api/v1/billing/dte?limit=2&cursor=eyJvIjoxNzU3..." \
  -H "X-Api-Key: $SIMPLO_API_KEY"
```

Cuando no quedan más páginas, `next_cursor` viene vacío o ausente. **No existe
un campo `total_count` en esta API**: no preguntes cuántas páginas faltan, itera
hasta que el cursor se acabe. Los cursores son opacos — nunca los parsees ni los
construyas.

## Con el SDK

El SDK (aún **no publicado en npm**, ver [SDK](/agentes/sdk/)) envuelve lo
anterior en `Page<T>` y puede recorrer todas las páginas por ti.

## El objeto `Page<T>`

```ts
const page = await simplo.dtes.list({ estado: 'aceptado', limit: 100 });

page.data;       // Dte[] — los items de esta página
page.hasMore;    // boolean
page.nextCursor; // string | null
page.totalCount; // number | undefined — total de coincidencias, cuando se reporta

const next = await page.getNextPage(); // Page<Dte> | null
```

`limit` va de 1 a 100 (default 20). Los filtros del listado de DTEs están
documentados en `ListDtesParams`: `tipo_dte`, `estado`, `fecha_desde`,
`fecha_hasta`, `rut_receptor`.

## Auto-paginación con `for await`

Un `Page` es un iterable asíncrono sobre **todos los items restantes**; las
páginas siguientes se piden de forma lazy a medida que el loop las alcanza:

```ts
for await (const dte of await simplo.dtes.list({ fecha_desde: '2026-08-01' })) {
  console.log(dte.folio, dte.monto_total);
}
```

Puedes cortar el loop en cualquier momento — después de eso no se piden más
páginas.

Juntar todo (ojo con la memoria en rangos grandes):

```ts
const all: Dte[] = [];
for await (const dte of await simplo.dtes.list(filters)) all.push(dte);
```

## Cursores manuales

Para checkpoints de jobs, persiste el cursor y retoma después:

```ts
let cursor: string | undefined = savedCursor;
do {
  const page = await simplo.dtes.list({ ...filters, cursor });
  await process(page.data);
  cursor = page.nextCursor ?? undefined;
  await saveCheckpoint(cursor);
} while (cursor !== undefined);
```

Los cursores son opacos — nunca los parsees ni los construyas.

## Listas sin paginación

`folios.list()` y `webhooks.list()` devuelven arrays planos: esas colecciones
son pequeñas por naturaleza (una empresa tiene un puñado de CAFs y de
endpoints de webhook).

---

Versión HTML: https://docs.simplo.cl/referencia/paginacion/ · Índice para agentes: https://docs.simplo.cl/llms.txt
