Paginacion
La API de FactuLink utiliza paginación basada en cursor para todos los endpoints que retornan listas de recursos. Este método es más eficiente y consistente que la paginación por offset, especialmente cuando los datos cambian frecuentemente.
Cómo funciona
En lugar de usar números de página, envías un cursor opaco que apunta al siguiente conjunto de resultados. Esto garantiza que no te saltes ni dupliques registros, incluso si se crean o eliminan recursos entre peticiones.
Parámetros de consulta
| Parámetro | Tipo | Default | Descripción |
|---|---|---|---|
limit | integer | 20 | Cantidad de registros por página. Mínimo: 1, máximo: 100. |
cursor | string | — | Token opaco del cursor. Omítelo en la primera petición. |
Ejemplo de petición
GET /api/v1/cfdis?limit=20&cursor=eyJpZCI6ImNmZGlfMDFKNUsuLi4iLCJjcmVhdGVkX2F0IjoiMjAyNi0wNC0wNVQxMDozMDowMFoifQFormato de respuesta
Todas las respuestas paginadas incluyen un objeto pagination junto al array data:
{
"data": [
{ "id": "cfdi_01J5K...", "serie": "A", "folio": 1042, "total": 11600.00 },
{ "id": "cfdi_01J5K...", "serie": "A", "folio": 1041, "total": 5800.00 }
],
"pagination": {
"has_more": true,
"next_cursor": "eyJpZCI6ImNmZGlfMDFKNUsuLi4iLCJjcmVhdGVkX2F0IjoiMjAyNi0wNC0wNVQxMDozMDowMFoifQ",
"limit": 20
}
}| Campo | Tipo | Descripción |
|---|---|---|
data | array | Lista de recursos de la página actual |
pagination.has_more | boolean | true si hay más resultados después de esta página |
pagination.next_cursor | string | Token para obtener la siguiente página. Solo presente si has_more es true. |
pagination.limit | integer | Límite aplicado en esta petición |
Cómo iterar todas las páginas
Para recorrer todos los resultados, repite las peticiones enviando el next_cursor hasta que has_more sea false:
- Haz la primera petición sin
cursor - Lee
pagination.has_morede la respuesta - Si es
true, haz otra petición usandopagination.next_cursorcomo parámetrocursor - Repite hasta que
has_moreseafalse
# Primera página
cursor=""
while true; do
if [ -z "$cursor" ]; then
response=$(curl -s https://api.factulink.com.mx/api/v1/cfdis?limit=20 \
-H "Authorization: Bearer sk_test_a1b2c3...")
else
response=$(curl -s "https://api.factulink.com.mx/api/v1/cfdis?limit=20&cursor=$cursor" \
-H "Authorization: Bearer sk_test_a1b2c3...")
fi
# Procesar los datos de esta página
echo "$response" | jq '.data'
# Verificar si hay más páginas
has_more=$(echo "$response" | jq -r '.pagination.has_more')
if [ "$has_more" != "true" ]; then
break
fi
cursor=$(echo "$response" | jq -r '.pagination.next_cursor')
doneBuenas prácticas
- No almacenes cursores a largo plazo. Los cursores son opacos y pueden expirar. Úsalos solo para iteración inmediata.
- Usa el
limitmás grande que necesites. Menos peticiones significan menos latencia total. Si necesitas todos los registros, usalimit=100. - No intentes decodificar el cursor. Su formato interno puede cambiar sin previo aviso. Trátalo siempre como un string opaco.
- Maneja errores entre páginas. Si una petición falla, puedes reintentar con el mismo cursor sin perder progreso.
Last updated on