Paginação com cursor da API Zendesk: Um guia completo para desenvolvedores

Stevia Putri
Written by

Stevia Putri

Reviewed by

Stanley Nicholas

Last edited 2 março 2026

Expert Verified

Imagem do banner para paginação com cursor da API Zendesk: Um guia completo para desenvolvedores

Se você estiver criando integrações com o Zendesk, descobrirá rapidamente que a API não entrega todo o seu banco de dados de tickets de uma só vez. Em vez disso, ela serve os dados em pedaços pequenos por meio de um mecanismo chamado paginação. Isso é por design. A paginação mantém a API responsiva e evita timeouts quando você está lidando com milhares (ou milhões) de tickets de suporte.

Mas é aqui que fica interessante. O Zendesk oferece duas maneiras diferentes de paginar seus dados: paginação com cursor e paginação por deslocamento (offset). Uma é rápida, moderna e virtualmente ilimitada. A outra é limitada a 10.000 registros e carrega alguma bagagem de designs de API mais antigos. Desde agosto de 2023, o Zendesk tem incentivado os desenvolvedores a usar a paginação com cursor, aplicando limites estritos ao método de deslocamento (offset).

Neste guia, vamos percorrer ambas as abordagens de paginação com exemplos de código funcionais. Você aprenderá quando usar cada método, como lidar com casos extremos e quais armadilhas evitar. E se você está pensando que deve haver uma maneira mais fácil de trabalhar com os dados do Zendesk sem escrever a lógica de paginação você mesmo, vamos abordar isso também.

Para mais contexto sobre as abordagens de paginação do Zendesk, você também pode achar útil nosso guia completo para paginar tickets do Zendesk.

Fluxograma de paginação com cursor mostrando o loop de solicitação-resposta para recuperar grandes conjuntos de dados
Fluxograma de paginação com cursor mostrando o loop de solicitação-resposta para recuperar grandes conjuntos de dados

Entendendo a paginação na API Zendesk

Antes de mergulharmos no código, vamos esclarecer por que a paginação existe e como ela funciona em alto nível.

A API Zendesk divide grandes conjuntos de resultados em páginas menores por motivos de desempenho. Solicitar 100.000 tickets em uma única chamada de API causaria timeout ou travaria a maioria dos sistemas. Em vez disso, você solicita a página 1, processa esses resultados, depois solicita a página 2 e assim por diante até ter recuperado tudo.

Diferentes endpoints têm diferentes tamanhos de página padrão:

  • Tickets e usuários: 100 itens por página
  • Artigos da Central de Ajuda: 30 itens por página
  • Resultados de pesquisa: 100 itens por página no máximo

Você geralmente pode ajustar o tamanho da página dentro dos limites, mas não pode exceder o máximo para nenhum endpoint específico.

Todas as solicitações de API contam para o seu limite de taxa. O Zendesk permite um certo número de solicitações por minuto, dependendo do seu plano, e a paginação pode consumir essa cota rapidamente se você estiver recuperando grandes conjuntos de dados. A boa notícia é que a paginação com cursor é mais eficiente do que a paginação por deslocamento (offset), então mudar de método pode realmente reduzir o uso da sua API.

Uma mudança crítica para saber: a partir de 15 de agosto de 2023, as solicitações de paginação baseadas em deslocamento (offset) além dos primeiros 10.000 registros (100 páginas) retornam um erro 400 Bad Request. Se você precisar de mais de 10.000 registros, a paginação com cursor agora é sua única opção. Saiba mais sobre esta mudança no anúncio de paginação por deslocamento (offset) do Zendesk.

Paginação com cursor vs paginação por deslocamento (offset)

Vamos detalhar as diferenças entre essas duas abordagens para que você possa escolher a certa para o seu caso de uso.

CaracterísticaPaginação com CursorPaginação por Deslocamento (Offset)
Limite de registroIlimitado10.000 no máximo
DesempenhoConsistente (rápido mesmo em páginas profundas)Degrada à medida que o número da página aumenta
Contagem total disponívelNãoSim (propriedade count)
Ir para página arbitráriaNão é possívelPossível
Consistência de dados durante a paginaçãoMelhorPropenso a duplicatas/registros perdidos
Recomendação do ZendeskRecomendadoSuporte legado apenas

Use a paginação com cursor quando:

  • Você precisa de mais de 10.000 registros
  • O desempenho é importante (especialmente para grandes conjuntos de dados)
  • Você está processando dados sequencialmente sem precisar pular

Use a paginação por deslocamento (offset) quando:

  • Você precisa da contagem total de registros
  • Você está construindo uma interface do usuário que permite aos usuários pular para páginas específicas
  • Você está trabalhando com um pequeno conjunto de dados (menos de 10.000 registros) e a simplicidade é importante

Se você estiver usando atualmente a paginação por deslocamento (offset) e atingindo o limite de 10.000 registros, migrar para a paginação com cursor é simples. As principais mudanças são:

  1. Substitua o parâmetro page por page[size]
  2. Verifique meta.has_more em vez de verificar se next_page é nulo
  3. Use links.next para o URL da próxima página em vez de next_page

Na eesel AI, nós nos integramos diretamente com o Zendesk e lidamos com toda a complexidade da paginação automaticamente. Mas se você estiver criando integrações personalizadas, entender essas diferenças é essencial.

Como funciona a paginação com cursor

A paginação com cursor usa um ponteiro (o cursor) que rastreia sua posição no conjunto de dados em vez de contar os registros desde o início a cada vez. Isso o torna significativamente mais rápido para grandes conjuntos de dados porque a API não precisa contar e pular registros para encontrar sua página.

Para habilitar a paginação com cursor, adicione um parâmetro page[size] à sua solicitação. Isso diz ao Zendesk que você deseja usar o modo de cursor e especifica quantos itens retornar por página (até 100 para a maioria dos endpoints). Consulte a documentação de paginação com cursor do Zendesk para obter detalhes completos.

A resposta inclui dois objetos-chave:

  • meta: Contém has_more (booleano), after_cursor e before_cursor
  • links: Contém URLs next e prev para as páginas adjacentes

Veja como é uma resposta 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=="
  }
}

Você continua paginando até que meta.has_more seja falso. Nesse ponto, você recuperou todos os registros.

Implementando a paginação com cursor em Python

Aqui está um exemplo completo e funcional usando Python e a 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)}')

Coisas importantes a serem observadas neste exemplo:

  • Começamos com page[size]=100 para habilitar a paginação com cursor
  • Verificamos o limite de taxa (HTTP 429) e respeitamos o cabeçalho Retry-After
  • Após a primeira solicitação, usamos o URL links.next diretamente para as páginas subsequentes
  • O loop continua até que has_more seja falso

Implementando a paginação com cursor em Node.js

Aqui está a mesma lógica em 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();

Armadilhas comuns e como evitá-las

Mesmo com código funcional, você encontrará casos extremos em produção. Veja como lidar com os problemas mais comuns.

Lidando com limites de taxa

O Zendesk retorna HTTP 429 quando você excede seu limite de taxa. A resposta inclui um cabeçalho Retry-After informando quantos segundos esperar. Sempre implemente o backoff exponencial em vez de bombardear a 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')

Lidando com páginas vazias

Ocasionalmente, você pode encontrar uma página vazia onde has_more era verdadeiro, mas a próxima solicitação não retorna nenhum registro. Isso pode acontecer quando o registro final da página anterior era o último registro em todo o conjunto de dados. Salve o valor after_cursor anterior para uso futuro neste caso.

Expiração do cursor

Para o endpoint Export Search Results, os cursores expiram após uma hora. Se o seu processamento demorar mais do que isso, você precisará reiniciar a exportação ou processar os dados mais rapidamente.

Limitações da API de pesquisa

A API de pesquisa tem suas próprias peculiaridades de paginação:

  • Máximo de 1.000 resultados por consulta no total
  • Máximo de 100 resultados por página
  • Usa apenas paginação por deslocamento (offset)
  • Solicitar a página 11 (com 100 resultados por página) retorna um erro 422

Se você precisar de mais de 1.000 resultados de pesquisa, use o endpoint Export Search Results, que suporta paginação com cursor e retorna até 1.000 registros por página. Consulte a documentação da API de pesquisa do Zendesk para obter mais detalhes.

Consistência de dados durante a paginação

Os dados paginados podem ser imprecisos devido à natureza em tempo real dos dados. Um ou mais itens podem ser adicionados ou removidos da sua instância de banco de dados entre as solicitações. Uma maneira de reduzir as imprecisões da paginação (embora não eliminá-las completamente) é classificar os registros por um atributo que não pode ser modificado, como o ID ou a data de criação, se isso for suportado pelo recurso.

Na eesel AI, nosso Agente de IA lida com essas complexidades automaticamente. Gerenciamos o limite de taxa, a expiração do cursor e os problemas de consistência de dados para que você não precise escrever essa lógica você mesmo.

Migrando da paginação por deslocamento (offset) para a paginação com cursor

Se você estiver usando atualmente a paginação por deslocamento (offset), aqui está um guia de migração rápido mostrando as principais mudanças:

Antes (paginação por deslocamento (offset)):

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

Depois (paginação com 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

As principais mudanças são:

  1. Adicione o parâmetro page[size] para habilitar o modo de cursor
  2. Verifique meta.has_more em vez de verificar se next_page é nulo
  3. Use links.next para o URL da próxima página em vez de next_page
  4. Remova a dependência da propriedade count (não disponível na paginação com cursor)

Ignore a complexidade da paginação com a eesel AI

Criar integrações de API personalizadas com paginação adequada, tratamento de erros e limite de taxa exige um esforço de desenvolvimento significativo. Você precisa escrever o código, mantê-lo à medida que o Zendesk atualiza sua API e lidar com todos os casos extremos que discutimos.

Para muitas equipes, existe um caminho mais simples. A eesel AI se conecta diretamente à sua conta Zendesk e lida com toda a recuperação de dados automaticamente. Em vez de escrever a lógica de paginação, você configura o que deseja realizar por meio de uma interface visual.

Veja como funciona:

  • Conecte a eesel AI à sua conta Zendesk em minutos
  • A IA aprende com seus tickets anteriores, artigos da central de ajuda e macros
  • Você define regras de automação em linguagem simples (sem necessidade de código)
  • A eesel AI lida com todas as chamadas de API, paginação e processamento de dados

Você pode automatizar o roteamento de tickets, redigir respostas para seus agentes, marcar e priorizar tickets recebidos e gerar relatórios. Tudo sem escrever uma única linha de código de paginação.

Para equipes que precisam de integrações personalizadas, a API Zendesk continua sendo a escolha certa. Mas se seu objetivo é automatizar fluxos de trabalho e melhorar a eficiência, ferramentas como a eesel AI podem levá-lo até lá mais rapidamente. Confira nossos preços para ver como nos comparamos à criação e manutenção de soluções personalizadas.

Página de preços da eesel AI mostrando custos públicos transparentes
Página de preços da eesel AI mostrando custos públicos transparentes

Perguntas Frequentes

Com a paginação com cursor, não há limite rígido. Você pode recuperar todo o seu banco de dados de tickets. Com a paginação por deslocamento (offset), você está limitado a 10.000 registros (100 páginas com 100 registros por página).
Fique atento às respostas HTTP 429 e respeite o cabeçalho Retry-After. Implemente o backoff exponencial para evitar atingir repetidamente o limite de taxa. Espere mais entre as tentativas com cada tentativa.
A maioria dos endpoints de lista suporta paginação com cursor, incluindo tickets, usuários e organizações. Verifique a documentação específica do endpoint para confirmar. Se a paginação com cursor não for mencionada, o endpoint provavelmente suporta apenas a paginação por deslocamento (offset).
As respostas de paginação com cursor não incluem uma contagem total. Você pode fazer uma chamada separada para um endpoint de contagem (como /api/v2/tickets/count.json) se precisar do número total de registros.
Sim, a paginação com cursor e por deslocamento (offset) funciona de forma consistente na maioria dos endpoints da API Zendesk, incluindo usuários, organizações e tickets. O mesmo parâmetro page[size] habilita a paginação com cursor para todos os endpoints suportados.
A API de pesquisa padrão usa apenas a paginação por deslocamento (offset) e retorna um máximo de 1.000 resultados. Para conjuntos de resultados maiores, use o endpoint Export Search Results, que suporta paginação com cursor.

Compartilhe esta postagem

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.