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. 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 con cursor y paginación por desplazamiento (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 con cursor mediante la aplicación de límites estrictos en el método de desplazamiento.
En esta guía, repasaremos ambos enfoques de paginación con ejemplos de código en funcionamiento. 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 manera más fácil de trabajar con los datos de Zendesk sin escribir la lógica de paginación usted mismo, también lo cubriremos.
Para obtener más contexto sobre los enfoques de paginación de Zendesk, también puede encontrar útil nuestra guía completa para paginar a través de los tickets de Zendesk.
Entendiendo la paginación en 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 agotaría el tiempo de espera o bloquearía la mayoría de los sistemas. En cambio, 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 para su límite de velocidad (rate limit). Zendesk permite una cierta cantidad de solicitudes por minuto según 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 con cursor es más eficiente que la paginación por desplazamiento, por lo que cambiar de método en realidad 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 desplazamiento 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 con cursor es ahora su única opción. Obtenga más información sobre este cambio en el anuncio de paginación por desplazamiento de Zendesk.
Paginación con cursor vs paginación por desplazamiento
Analicemos las diferencias entre estos dos enfoques para que pueda elegir el correcto para su caso de uso.
| Característica | Paginación con cursor | Paginación por desplazamiento |
|---|---|---|
| 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 con 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 desplazamiento 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 conjunto de datos pequeño (menos de 10,000 registros) y la simplicidad importa
Si actualmente está utilizando la paginación por desplazamiento y alcanza el límite de 10,000 registros, la migración a la paginación con cursor es sencilla. 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
En eesel AI, nos integramos directamente con Zendesk y manejamos toda la complejidad de la paginación automáticamente. Pero si está creando integraciones personalizadas, comprender estas diferencias es esencial.
Cómo funciona la paginación con cursor
La paginación con cursor 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.
Para habilitar la paginación con cursor, agregue un parámetro page[size] a su solicitud. Esto le dice a Zendesk que desea usar el modo cursor y especifica cuántos elementos devolver por página (hasta 100 para la mayoría de los endpoints). Consulte la documentación de paginación con cursor de Zendesk para obtener detalles completos.
La respuesta incluye dos objetos clave:
- meta: Contiene
has_more(booleano),after_cursorybefore_cursor - links: Contiene las URL
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.
Implementación de la paginación con cursor en Python
Aquí hay un ejemplo completo que funciona con 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 con 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
Implementación de la paginación con cursor en Node.js
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();
Trampas comunes y cómo evitarlas
Incluso con el código en funcionamiento, encontrará casos extremos en producción. Aquí le mostramos 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 after_cursor anterior para usarlo en el futuro en este caso.
Vencimiento del cursor
Para el endpoint Export Search Results, los cursores caducan después de una hora. Si su procesamiento lleva más tiempo, 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 desplazamiento
- 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 con 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.
Consistencia de los datos durante la paginación
Los datos paginados pueden ser inexactos debido a la naturaleza en tiempo real de los datos. Uno o más elementos pueden agregarse o eliminarse de su instancia de base de datos entre solicitudes. Una forma de reducir las imprecisiones de la paginación (aunque no eliminarlas por completo) es ordenar los registros por un atributo que no se pueda modificar, como el ID o la fecha de creación, si el recurso lo admite.
En eesel AI, nuestro Agente de IA maneja estas complejidades automáticamente. Gestionamos los límites de velocidad, el vencimiento del cursor y los problemas de coherencia de los datos para que no tenga que escribir esa lógica usted mismo.
Migración de la paginación por desplazamiento a la paginación con cursor
Si actualmente está utilizando la paginación por desplazamiento, aquí hay una guía de migración rápida que muestra los cambios clave:
Antes (paginación por desplazamiento):
url = f'https://{subdomain}.zendesk.com/api/v2/tickets.json'
while url:
response = requests.get(url, auth=auth)
data = response.json()
# Process tickets...
url = data['next_page'] # null when done
Después (paginación con cursor):
url = f'https://{subdomain}.zendesk.com/api/v2/tickets.json?page[size]=100'
params = {'page[size]': 100}
while url:
response = requests.get(url, auth=auth, params=params)
data = response.json()
# Process tickets...
if data['meta']['has_more']:
url = data['links']['next']
params = None
else:
url = None
Los principales cambios son:
- Agregue el parámetro
page[size]para habilitar el modo cursor - Verifique
meta.has_moreen lugar de sinext_pagees nulo - Use
links.nextpara la URL de la página siguiente en lugar denext_page - Elimine la dependencia de la propiedad
count(no disponible en la paginación con cursor)
Omita la complejidad de la paginación con eesel AI
La creación de integraciones de API personalizadas con la paginación, el manejo de errores y los límites de velocidad adecuados requiere un esfuerzo de desarrollo significativo. Debe escribir el código, mantenerlo a medida que Zendesk actualiza su API y manejar todos los casos extremos que hemos discutido.
Para muchos equipos, existe 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 desea 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 anteriores, artículos del centro de ayuda y macros
- Define reglas de automatización en inglés 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. Consulte nuestros precios para ver cómo nos comparamos con la creación y el mantenimiento de soluciones personalizadas.

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.



