Conceptos
Paginación
Las dos formas de lista del gateway (Page con número de página y OffsetPage con limit/offset) y cómo recorrerlas completas en Python, JavaScript/TypeScript, PHP, .NET y Go.
En esta página
Las listas del gateway vienen en una de dos formas:
| Forma | Campos | Parámetros | Dónde |
|---|---|---|---|
Page | count, results, next, previous | page, page_size | Bandejas de créditos y subsidios, cuota monetaria, PQRS, salud (citas, facturas, glosas, agenda), administrativo, entregas de webhooks, cartera |
OffsetPage | results, limit, offset, has_more, next_offset | limit, offset | Movimientos de la billetera y pagos de facturas |
En todos los SDK una página es iterable sobre sus results y conserva el cuerpo original en
raw. Lo que cambia es cómo se piden las siguientes.
| SDK | Page | OffsetPage | Recorrido automático |
|---|---|---|---|
| Python | Page (count, results, next) | OffsetPage (has_more, next_offset) | Bucle propio con page= / offset= |
| JavaScript / TS | Page | OffsetPage | for await (const x of page), page.iterPages(), page.getNextPage() |
| PHP | Page (hasNext()) | OffsetPage (hasMore, nextOffset) | Bucle do … while |
| .NET | Page | OffsetPage | …AutoPagingAsync() → IAsyncEnumerable<JsonObject> |
| Go | *Page (HasNext()) | *OffsetPage (HasMore, NextOffset) | NewPageIterator / NewOffsetIterator (y it.All() con Go 1.23+) |
Recorrer una lista por páginas #
Ejemplo: todas las PQRS abiertas y vencidas de Caja Horizonte, de 50 en 50.
page_no = 1
while True:
page = client.pqrs.list(status="opened", overdue=True, page=page_no, page_size=50)
for pqrs in page:
escalate(pqrs)
if not page.next:
break
page_no += 1const first = await client.pqrs.list({ status: "opened", overdue: true, pageSize: 50 });
for await (const pqrs of first) { // pide las páginas siguientes con los mismos filtros
await escalate(pqrs);
}$n = 1;
do {
$page = $client->pqrs->list(status: 'opened', overdue: true, page: $n++, pageSize: 50);
foreach ($page as $pqrs) {
escalate($pqrs);
}
} while ($page->hasNext());await foreach (var pqrs in client.Pqrs.ListAutoPagingAsync(status: "opened", overdue: true, pageSize: 50))
{
await EscalateAsync(pqrs);
}it := compense.NewPageIterator(ctx, func(ctx context.Context, page int) (*compense.Page, error) {
return client.PQRS.List(ctx, &compense.PQRSListParams{
Status: "opened", Overdue: compense.Bool(true), Page: page, PageSize: 50,
})
})
for it.Next() {
escalate(it.Item())
}
if err := it.Err(); err != nil {
log.Fatal(err)
}page=1
while :; do
resp=$(curl -s "https://sandbox.dev.compense.co/gw/v1/gateway/pqrs/?status=opened&overdue=true&page=$page&page_size=50" \
-H "X-API-Key: $COMPENSE_API_KEY")
echo "$resp" | jq -c '.results[]'
[ "$(echo "$resp" | jq -r '.next')" = "null" ] && break
page=$((page + 1))
doneRecorrer una lista con limit/offset #
Ejemplo: todos los movimientos de octubre de la billetera de un usuario de Nova.
offset = 0
while True:
page = client.wallet.transactions.list("1032456789", start_date="2026-10-01",
end_date="2026-10-31", limit=100, offset=offset)
for movement in page:
export(movement)
if not page.has_more or page.next_offset is None:
break
offset = page.next_offsetconst first = await client.wallet.transactions.list("1032456789", {
startDate: "2026-10-01", endDate: "2026-10-31", limit: 100,
});
for await (const movement of first) {
await exportMovement(movement);
}$offset = null;
do {
$page = $client->wallet->transactions->list('1032456789', startDate: '2026-10-01',
endDate: '2026-10-31', limit: 100, offset: $offset);
foreach ($page as $movement) {
export_movement($movement);
}
$offset = $page->nextOffset;
} while ($page->hasMore && $offset !== null);await foreach (var movement in client.Wallet.Transactions.ListAutoPagingAsync(
"1032456789", startDate: "2026-10-01", endDate: "2026-10-31", limit: 100))
{
await ExportAsync(movement);
}it := compense.NewOffsetIterator(ctx, func(ctx context.Context, offset int) (*compense.OffsetPage, error) {
return client.Wallet.Transactions.List(ctx, "1032456789", &compense.WalletTransactionsParams{
StartDate: "2026-10-01", EndDate: "2026-10-31", Limit: 100, Offset: offset,
})
})
for item, err := range it.All() { // Go 1.23+; con 1.21 usa it.Next() / it.Item()
if err != nil {
log.Fatal(err)
}
export(item)
}offset=0
while :; do
resp=$(curl -s "https://sandbox.dev.compense.co/gw/v1/gateway/wallet/transactions/?document=1032456789&start_date=2026-10-01&end_date=2026-10-31&limit=100&offset=$offset" \
-H "X-API-Key: $COMPENSE_API_KEY")
echo "$resp" | jq -c '.results[]'
[ "$(echo "$resp" | jq -r '.has_more')" = "true" ] || break
offset=$(echo "$resp" | jq -r '.next_offset')
doneCuidados #
- Límites de página.
page_sizeva de 1 a 100 (25 por defecto en la mayoría);limitde 1 a 100 (50 por defecto en movimientos). Pedir más no da error: se recorta. - El recorrido automático sigue
next. Los iteradores de JS, .NET y Go (yhasNext()en PHP) avanzan mientras la respuesta traenext. Algunas listas no lo incluyen —por ejemplo, el historial de entregas de webhooks devuelvecount,pageypage_size—, y entonces el recorrido automático se queda en la primera página. En esas listas avanza tú comparando lo recibido concount(ejemplo en reintentos de webhooks). - Listas que no paginan. Algunas operaciones devuelven todo en una sola página (por ejemplo,
los créditos de un afiliado y las listas administrativas sin parámetro de página): ahí
hasNextPage()/HasNext()es falso. - Datos que cambian mientras recorres. Si se crean registros durante el recorrido, una página
puede repetir o saltar elementos. Para exportaciones completas, filtra por un rango de fechas
cerrado y deduplica por
id.