Paginação
Os endpoints de listagem (GET /v1/vms, GET /v1/snapshots etc.) paginam com cursores opacos, não com offsets numéricos. A paginação por cursor é o padrão certo para listas de recursos que mudam enquanto você pagina — ela retorna cada item exatamente uma vez, mesmo que linhas sejam inseridas ou excluídas entre as buscas de página.
O formato
Dois parâmetros de query em todo endpoint de listagem:
limit— tamanho de página. Padrão 50, máximo 200. Acima de 200, a requisição falha na validação:422validation_error(Erros).cursor— ponteiro opaco para a próxima página. Omita na primeira requisição.
Toda resposta de listagem inclui:
{
"items": [ /* ... */ ],
"pagination": {
"next_cursor": "eyJpZCI6InZtXzAxSEc3Li4uIn0=",
"total_count": null
}
}Quando next_cursor é null, você chegou à última página.
Percorrer as páginas
async function listAllVms(): Promise<VM[]> {
const all: VM[] = []
let cursor: string | undefined
do {
const url = new URL('https://api.nimbusnexus.net/v1/vms')
url.searchParams.set('limit', '200')
if (cursor) url.searchParams.set('cursor', cursor)
const res = await fetch(url, { headers: auth })
const { items, pagination } = await res.json()
all.push(...items)
cursor = pagination.next_cursor ?? undefined
} while (cursor)
return all
}Três regras:
- Os cursores são opacos. Não tente interpretá-los nem construí-los. Eles codificam o estado de ordenação + filtros da sua requisição original, então um cursor de uma consulta não funciona em outra.
- Não mude os filtros no meio da paginação. Se você começa com
?status=runninge depois adiciona?region=us-east-1na página 2, o comportamento é indefinido. Recomece do zero (sem cursor) quando os filtros mudarem. - Pare quando
next_cursorfor null. Não tente continuar paginando "por via das dúvidas" — o cursor é o único sinal confiável de fim da lista.
Por que cursores e não ?page=2&per_page=50
A paginação por offset quebra em dois cenários reais:
Inserções durante a paginação. Se você busca a página 1 (itens 1–50), alguém cria uma VM nova e depois você busca a página 2 (itens 51–100), você vê o item 50 duas vezes (agora ele está na posição 51) e nunca vê o item novo. Os cursores capturam "onde você estava" — a próxima página começa depois de onde você realmente estava, não em um offset absoluto.
Exclusões durante a paginação. O mesmo problema ao contrário: se uma VM é excluída entre as buscas de página, um cliente que pagina por offset pula um item. Clientes que paginam por cursor não pulam.
Esses casos extremos importam em qualquer escala não trivial. Usamos paginação por cursor por padrão para que eles não causem problemas para você.
total_count
O campo total_count em pagination é null na maioria dos endpoints, de propósito. Contar todos os itens de uma lista paginada é uma consulta cara que fica menos útil à medida que N cresce ("você tem 14.328 VMs em todos os seus projetos" — o que fazer com isso?). Quando total_count está presente, a página de referência do endpoint o documenta; quando está ausente, não dependa dele.
Se você realmente precisa de uma contagem exata, pagine até o fim e conte o que recebeu.
Ordenação
Os endpoints de listagem têm uma ordenação padrão (geralmente created_at desc, os mais novos primeiro), documentada por endpoint. Alguns endpoints aceitam ?sort= para substituí-la; a página de referência lista o que é aceito.
O cursor codifica a ordenação, então mudar ?sort= entre as buscas de página é um dos casos de "comportamento indefinido" — recomece do zero quando mudá-la.
Filtros
Todo endpoint de listagem aceita alguns parâmetros de filtro padrão:
created_after/created_before— timestamps RFC 3339updated_after/updated_before— timestamps RFC 3339- Filtros específicos do recurso (por exemplo,
?region=us-east-1&state=runningem VMs)
Os filtros se combinam; a resposta é o AND de todos os filtros. A página de referência do recurso documenta quais filtros ele aceita.
Quando você realmente quer todos os itens
Chamar a listagem paginada em um loop apertado para enumerar todos os recursos serve para trabalho pontual, mas sai caro para daemons que rodam repetidamente. Dois padrões melhores:
- Webhooks. Inscreva-se nos eventos
resource.created/resource.deletede mantenha seu próprio índice. Veja Webhooks da plataforma. - Endpoints de exportação em lote. Para alguns recursos (snapshots, backups, logs de auditoria), há um endpoint de exportação dedicado que transmite o conjunto completo em uma única resposta. A página de referência do recurso documenta esses endpoints onde eles existem.
O padrão de paginação é para uso interativo (uma tabela no painel, um comando de listagem na CLI). Para sincronização contínua, o custo da paginação domina e os webhooks são a resposta certa.
Próximos passos
- Convenções — o resto do formato da requisição (códigos de status, erros, idempotência).
- Webhooks da plataforma — alternativa baseada em push para sincronização contínua.
- A página de referência de qualquer endpoint de listagem — filtros e opções de ordenação específicos do endpoint.