Si está creando integraciones con Zendesk, rápidamente descubrirá que la API no entrega toda su base de datos de tickets de una sola vez. En cambio, sirve los datos en fragmentos pequeños a través de un mecanismo llamado paginación (pagination). Esto es por diseño. La paginación mantiene la API receptiva y evita los tiempos de espera cuando se trata de miles (o millones) de tickets de soporte.
Pero aquí es donde se pone interesante. Zendesk ofrece dos formas diferentes de paginar a través de sus datos: paginación por cursor (cursor pagination) y paginación por offset (offset pagination). Una es rápida, moderna y virtualmente ilimitada. La otra está limitada a 10,000 registros y conlleva algo de bagaje de diseños de API más antiguos. Desde agosto de 2023, Zendesk ha estado impulsando a los desarrolladores hacia la paginación por cursor mediante la aplicación de límites estrictos en el método de offset.
En esta guía, recorreremos ambos enfoques de paginación con ejemplos de código funcionales. Aprenderá cuándo usar cada método, cómo manejar los casos extremos y qué trampas evitar. Y si está pensando que debe haber una forma más fácil de automatizar los flujos de trabajo de Zendesk sin escribir la lógica de paginación usted mismo, también lo cubriremos.
Entendiendo la paginación de la API de Zendesk
Antes de sumergirnos en el código, aclaremos por qué existe la paginación y cómo funciona a un alto nivel.
La API de Zendesk divide los grandes conjuntos de resultados en páginas más pequeñas por razones de rendimiento. Solicitar 100,000 tickets en una sola llamada a la API provocaría un tiempo de espera o bloquearía la mayoría de los sistemas. En cambio, usted solicita la página 1, procesa esos resultados, luego solicita la página 2, y así sucesivamente hasta que haya recuperado todo.
Diferentes endpoints tienen diferentes tamaños de página predeterminados:
- Tickets y usuarios: 100 elementos por página
- Artículos del Centro de ayuda: 30 elementos por página
- Resultados de búsqueda: 100 elementos por página como máximo
Por lo general, puede ajustar el tamaño de la página dentro de los límites, pero no puede exceder el máximo para ningún endpoint dado.
Todas las solicitudes a la API cuentan en contra de su límite de velocidad (rate limit). Zendesk permite un cierto número de solicitudes por minuto dependiendo de su plan, y la paginación puede consumir esa cuota rápidamente si está recuperando grandes conjuntos de datos. La buena noticia es que la paginación por cursor es más eficiente que la paginación por offset, por lo que cambiar de método puede reducir su uso de la API.
Un cambio crítico que debe conocer: a partir del 15 de agosto de 2023, las solicitudes de paginación basadas en offset más allá de los primeros 10,000 registros (100 páginas) devuelven un error 400 Bad Request. Si necesita más de 10,000 registros, la paginación por cursor es ahora su única opción. Obtenga más información sobre este cambio en el anuncio de la paginación por offset de Zendesk.
Paginación por cursor: el método recomendado
La paginación por cursor es el enfoque preferido de Zendesk para la mayoría de los endpoints de lista. Utiliza un puntero (el cursor) que rastrea su posición en el conjunto de datos en lugar de contar los registros desde el principio cada vez. Esto lo hace significativamente más rápido para grandes conjuntos de datos porque la API no necesita contar y omitir registros para encontrar su página.
Cómo funciona la paginación por cursor
Para habilitar la paginación por cursor, agregue un parámetro page[size] a su solicitud. Esto le dice a Zendesk que quiere usar el modo de cursor y especifica cuántos elementos devolver por página (hasta 100 para la mayoría de los endpoints).
La respuesta incluye dos objetos clave:
- meta: Contiene
has_more(booleano),after_cursorybefore_cursor - links: Contiene las URLs
nextyprevpara las páginas adyacentes
Así es como se ve una respuesta típica:
{
"tickets": [
{ "id": 1, "subject": "Sample ticket" },
{ "id": 2, "subject": "Another ticket" }
],
"meta": {
"has_more": true,
"after_cursor": "eyJvIjoibmljZV9pZCIsInYiOiJhV2tCQUFBQUFBQUEifQ==",
"before_cursor": "eyJvIjoibmljZV9pZCIsInYiOiJhUzRCQUFBQUFBQUEifQ=="
},
"links": {
"next": "https://example.zendesk.com/api/v2/tickets.json?page[size]=100&page[after]=eyJvIjoibmljZV9pZCIsInYiOiJhV2tCQUFBQUFBQUEifQ==",
"prev": "https://example.zendesk.com/api/v2/tickets.json?page[size]=100&page[before]=eyJvIjoibmljZV9pZCIsInYiOiJhUzRCQUFBQUFBQUEifQ=="
}
}
Sigue paginando hasta que meta.has_more sea falso. En ese punto, ha recuperado todos los registros.
Ejemplo de Python con paginación por cursor
Aquí hay un ejemplo completo que funciona usando Python y la biblioteca requests:
import requests
import time
ZENDESK_SUBDOMAIN = 'your-subdomain'
ZENDESK_EMAIL = 'your-email@example.com'
ZENDESK_API_TOKEN = 'your-api-token'
BASE_URL = f'https://{ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json'
auth = (f'{ZENDESK_EMAIL}/token', ZENDESK_API_TOKEN)
def fetch_all_tickets():
tickets = []
url = BASE_URL
params = {'page[size]': 100} # Use cursor pagination with 100 items per page
while url:
response = requests.get(url, auth=auth, params=params)
# Handle rate limiting
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f'Rate limited. Waiting {retry_after} seconds...')
time.sleep(retry_after)
continue
response.raise_for_status()
data = response.json()
# Process tickets from this page
for ticket in data['tickets']:
tickets.append(ticket)
print(f"Fetched ticket {ticket['id']}: {ticket['subject']}")
# Check if there are more pages
if data['meta']['has_more']:
url = data['links']['next']
params = None # Next URL already includes all parameters
else:
url = None
return tickets
if __name__ == '__main__':
all_tickets = fetch_all_tickets()
print(f'\nTotal tickets fetched: {len(all_tickets)}')
Cosas clave a tener en cuenta en este ejemplo:
- Comenzamos con
page[size]=100para habilitar la paginación por cursor - Verificamos el límite de velocidad (HTTP 429) y respetamos el encabezado Retry-After
- Después de la primera solicitud, usamos la URL
links.nextdirectamente para las páginas subsiguientes - El bucle continúa hasta que
has_moresea falso
Ejemplo de Node.js con paginación por cursor
Aquí está la misma lógica en Node.js usando axios:
const axios = require('axios');
const ZENDESK_SUBDOMAIN = 'your-subdomain';
const ZENDESK_EMAIL = 'your-email@example.com';
const ZENDESK_API_TOKEN = 'your-api-token';
const BASE_URL = `https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json`;
const auth = Buffer.from(`${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}`).toString('base64');
async function fetchAllTickets() {
const tickets = [];
let url = BASE_URL;
let params = { 'page[size]': 100 };
try {
do {
const response = await axios.get(url, {
headers: { Authorization: `Basic ${auth}` },
params: params
});
const data = response.data;
// Process tickets from this page
for (const ticket of data.tickets) {
tickets.push(ticket);
console.log(`Fetched ticket ${ticket.id}: ${ticket.subject}`);
}
// Prepare for next page
if (data.meta.has_more) {
url = data.links.next;
params = null; // Next URL includes all parameters
} else {
url = null;
}
} while (url);
console.log(`\nTotal tickets fetched: ${tickets.length}`);
return tickets;
} catch (error) {
if (error.response && error.response.status === 429) {
const retryAfter = error.response.headers['retry-after'] || 60;
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
} else {
console.error('Error fetching tickets:', error.message);
}
throw error;
}
}
fetchAllTickets();
Paginación por offset: el método heredado
La paginación por offset es el enfoque más antiguo que Zendesk todavía admite, pero ya no recomienda. Funciona especificando un número de página y la API calcula qué registros devolver en función de ese offset desde el principio del conjunto de datos.
Cómo funciona la paginación por offset
Con la paginación por offset, utiliza el parámetro page para solicitar un número de página específico, y opcionalmente per_page para establecer el número de elementos por página (hasta 100).
La respuesta incluye:
- next_page: URL para la página siguiente, o null si está en la última página
- previous_page: URL para la página anterior, o null si está en la primera página
- count: Número total de registros en el conjunto de datos
Aquí hay una respuesta típica:
{
"tickets": [
{ "id": 1, "subject": "Sample ticket" },
{ "id": 2, "subject": "Another ticket" }
],
"count": 15420,
"next_page": "https://example.zendesk.com/api/v2/tickets.json?page=2",
"previous_page": null
}
Ejemplo de Python con paginación por offset
Aquí se explica cómo paginar usando el método de offset:
import requests
import time
ZENDESK_SUBDOMAIN = 'your-subdomain'
ZENDESK_EMAIL = 'your-email@example.com'
ZENDESK_API_TOKEN = 'your-api-token'
BASE_URL = f'https://{ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json'
auth = (f'{ZENDESK_EMAIL}/token', ZENDESK_API_TOKEN)
def fetch_tickets_offset():
tickets = []
url = BASE_URL
while url:
response = requests.get(url, auth=auth)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
continue
if response.status_code == 400:
# You've hit the 10,000 record limit
print('Error: Cannot paginate beyond 10,000 records with offset pagination')
break
response.raise_for_status()
data = response.json()
for ticket in data['tickets']:
tickets.append(ticket)
# Move to next page
url = data['next_page']
return tickets
Limitaciones a tener en cuenta
La paginación por offset tiene varios inconvenientes que explican por qué Zendesk la está eliminando gradualmente:
-
El límite estricto de 10,000 registros: No puede recuperar más de 10,000 registros usando la paginación por offset. Intentar solicitar la página 101 o posterior devuelve un error 400.
-
Degradación del rendimiento: A medida que solicita páginas más profundas (página 50, página 90), la API tarda más en responder porque debe contar y omitir todos los registros anteriores.
-
Inconsistencia de datos: Si se agregan o eliminan registros mientras está paginando, puede ver duplicados o perder registros. Esto sucede porque el offset se calcula de nuevo para cada solicitud en función del estado actual del conjunto de datos.
-
Sin recuento total con paginación por cursor: Una ventaja de la paginación por offset es que devuelve un
countde registros totales. La paginación por cursor no proporciona esto, por lo que necesitará una llamada a la API separada si necesita el total.
Cursor vs offset: ¿cuál debería usar?
La elección es sencilla para la mayoría de los casos de uso:
| Característica | Paginación por Cursor | Paginación por Offset |
|---|---|---|
| Límite de registros | Ilimitado | 10,000 máximo |
| Rendimiento | Consistente (rápido incluso en páginas profundas) | Se degrada a medida que aumenta el número de página |
| Recuento total disponible | No | Sí (propiedad count) |
| Saltar a una página arbitraria | No es posible | Posible |
| Consistencia de datos durante la paginación | Mejor | Propenso a duplicados/registros perdidos |
| Recomendación de Zendesk | Recomendado | Solo soporte heredado |
Use la paginación por cursor cuando:
- Necesita más de 10,000 registros
- El rendimiento importa (especialmente para grandes conjuntos de datos)
- Está procesando datos secuencialmente sin necesidad de saltar
Use la paginación por offset cuando:
- Necesita el recuento total de registros
- Está construyendo una interfaz de usuario que permite a los usuarios saltar a páginas específicas
- Está trabajando con un pequeño conjunto de datos (menos de 10,000 registros) y la simplicidad importa
Si actualmente está utilizando la paginación por offset y alcanza el límite de 10,000 registros, migrar a la paginación por cursor es sencillo. Los principales cambios son:
- Reemplace el parámetro
pageconpage[size] - Verifique
meta.has_moreen lugar de sinext_pagees nulo - Use
links.nextpara la URL de la página siguiente en lugar denext_page
Trampas comunes de la paginación y soluciones
Incluso con código funcional, encontrará casos extremos en producción. Aquí se explica cómo manejar los problemas más comunes.
Manejo de límites de velocidad
Zendesk devuelve HTTP 429 cuando excede su límite de velocidad. La respuesta incluye un encabezado Retry-After que le indica cuántos segundos debe esperar. Siempre implemente una retroceso exponencial en lugar de bombardear la API:
import time
def make_request_with_backoff(url, auth, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url, auth=auth)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
# Exponential backoff: wait longer with each retry
wait_time = retry_after * (2 ** attempt)
time.sleep(wait_time)
continue
return response
raise Exception('Max retries exceeded')
Lidiar con páginas vacías
Ocasionalmente, puede encontrar una página vacía donde has_more era verdadero, pero la siguiente solicitud no devuelve registros. Esto puede suceder cuando el registro final de la página anterior fue el último registro en todo el conjunto de datos. Guarde el valor anterior de after_cursor para uso futuro en este caso.
Expiración del cursor
Para el endpoint Export Search Results, los cursores expiran después de una hora. Si su procesamiento lleva más tiempo que eso, deberá reiniciar la exportación o procesar los datos más rápidamente.
Limitaciones de la API de búsqueda
La API de búsqueda tiene sus propias peculiaridades de paginación:
- Máximo 1,000 resultados por consulta en total
- Máximo 100 resultados por página
- Utiliza solo la paginación por offset
- Solicitar la página 11 (a 100 resultados por página) devuelve un error 422
Si necesita más de 1,000 resultados de búsqueda, utilice el endpoint Export Search Results en su lugar, que admite la paginación por cursor y devuelve hasta 1,000 registros por página. Consulte la documentación de la API de búsqueda de Zendesk para obtener más detalles.
Automatización de flujos de trabajo de Zendesk sin la API
La creación de integraciones de API personalizadas con la paginación, el manejo de errores y el límite de velocidad adecuados requiere un esfuerzo de desarrollo significativo. Necesita escribir el código, mantenerlo a medida que Zendesk actualiza su API y manejar todos los casos extremos que hemos discutido.
Para muchos equipos, hay un camino más simple. eesel AI se conecta directamente a su cuenta de Zendesk y maneja toda la recuperación de datos automáticamente. En lugar de escribir la lógica de paginación, configura lo que quiere lograr a través de una interfaz visual.

Así es como funciona:
- Conecte eesel AI a su cuenta de Zendesk en minutos
- La IA aprende de sus tickets pasados, artículos del centro de ayuda y macros
- Usted define las reglas de automatización en lenguaje sencillo (no se requiere código)
- eesel AI maneja todas las llamadas a la API, la paginación y el procesamiento de datos
Puede automatizar el enrutamiento de tickets, redactar respuestas para sus agentes, etiquetar y priorizar los tickets entrantes y generar informes. Todo sin escribir una sola línea de código de paginación.
Para los equipos que necesitan integraciones personalizadas, la API de Zendesk sigue siendo la opción correcta. Pero si su objetivo es automatizar los flujos de trabajo y mejorar la eficiencia, herramientas como eesel AI pueden llevarlo allí más rápido.
Comience a automatizar sus flujos de trabajo de Zendesk hoy mismo
La paginación es un concepto fundamental cuando se trabaja con la API de Zendesk. La paginación por cursor ofrece un mejor rendimiento y sin límites de registro, lo que la convierte en la opción clara para la mayoría de las integraciones modernas. La paginación por offset todavía tiene su lugar para conjuntos de datos más pequeños y cuando necesita recuentos totales de registros, pero el límite de 10,000 registros significa que no es adecuada para la recuperación de datos a gran escala.
Los ejemplos de código en esta guía deberían darle una base sólida para implementar la paginación en sus propios proyectos. Recuerde manejar los límites de velocidad con elegancia, esté atento a los casos extremos como las páginas vacías y elija el método de paginación que se ajuste a su caso de uso específico.
Si prefiere omitir el desarrollo de la API por completo y comenzar a automatizar sus flujos de trabajo de Zendesk hoy mismo, pruebe eesel AI. Maneja la complejidad técnica para que pueda concentrarse en brindar una mejor atención al cliente.
Preguntas Frecuentes
Compartir esta entrada

Article by
Stevia Putri
Stevia Putri is a marketing generalist at eesel AI, where she helps turn powerful AI tools into stories that resonate. She’s driven by curiosity, clarity, and the human side of technology.



