Paginación con cursor de la API de Zendesk: Una guía completa para desarrolladores

Stevia Putri
Written by

Stevia Putri

Reviewed by

Stanley Nicholas

Last edited 2 marzo 2026

Expert Verified

Imagen del banner para la paginación con cursor de la API de Zendesk: Una guía completa para desarrolladores

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.

Diagrama de flujo de paginación con cursor que muestra el bucle de solicitud-respuesta para recuperar grandes conjuntos de datos
Diagrama de flujo de paginación con cursor que muestra el bucle de solicitud-respuesta para recuperar grandes conjuntos de datos

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ísticaPaginación con cursorPaginación por desplazamiento
Límite de registrosIlimitado10,000 máximo
RendimientoConsistente (rápido incluso en páginas profundas)Se degrada a medida que aumenta el número de página
Recuento total disponibleNoSí (propiedad count)
Saltar a una página arbitrariaNo es posiblePosible
Consistencia de datos durante la paginaciónMejorPropenso a duplicados/registros perdidos
Recomendación de ZendeskRecomendadoSolo 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:

  1. Reemplace el parámetro page con page[size]
  2. Verifique meta.has_more en lugar de si next_page es nulo
  3. Use links.next para la URL de la página siguiente en lugar de next_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_cursor y before_cursor
  • links: Contiene las URL next y prev para 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]=100 para 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.next directamente para las páginas subsiguientes
  • El bucle continúa hasta que has_more sea 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:

  1. Agregue el parámetro page[size] para habilitar el modo cursor
  2. Verifique meta.has_more en lugar de si next_page es nulo
  3. Use links.next para la URL de la página siguiente en lugar de next_page
  4. 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.

Página de precios de eesel AI que muestra costos públicos transparentes
Página de precios de eesel AI que muestra costos públicos transparentes

Preguntas Frecuentes

Con la paginación con cursor, no hay un límite estricto. Puede recuperar toda su base de datos de tickets. Con la paginación por desplazamiento (offset pagination), está limitado a 10,000 registros (100 páginas a 100 registros por página).
Esté atento a las respuestas HTTP 429 y respete el encabezado Retry-After. Implemente una retroceso exponencial (exponential backoff) para evitar alcanzar repetidamente el límite de velocidad. Espere más tiempo entre reintentos con cada intento.
La mayoría de los endpoints de lista admiten la paginación con cursor, incluidos los tickets, los usuarios y las organizaciones. Consulte la documentación específica del endpoint para confirmarlo. Si no se menciona la paginación con cursor, es probable que el endpoint solo admita la paginación por desplazamiento.
Las respuestas de paginación con cursor no incluyen un recuento total. Puede realizar una llamada separada a un endpoint de recuento (como /api/v2/tickets/count.json) si necesita el número total de registros.
Sí, la paginación con cursor y por desplazamiento funciona de manera consistente en la mayoría de los endpoints de la API de Zendesk, incluidos los usuarios, las organizaciones y los tickets. El mismo parámetro page[size] habilita la paginación con cursor para todos los endpoints admitidos.
La API de búsqueda estándar utiliza solo la paginación por desplazamiento y devuelve un máximo de 1,000 resultados. Para conjuntos de resultados más grandes, utilice el endpoint Export Search Results que admite la paginación con cursor.

Compartir esta entrada

Stevia undefined

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.