Paginação por cursor
Atualizado em
Todas as rotas de listagem da API usam paginação por cursor. Ela não pula nem repete registros quando novas notas são emitidas enquanto você percorre a lista.
Parâmetros#
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
limit |
inteiro | 50 |
Itens por página, de 1 a 200 |
cursor |
string | — | Valor de next_cursor da página anterior. Omita na primeira página |
Resposta#
Resposta
{
"status": "success",
"message": "Operação realizada com sucesso",
"data": {
"items": [ { "id": "3c9b7e1a-6d42-4f8e-a0b3-7e2f5d1c9a84", "status": "authorized" } ],
"next_cursor": "eyJjIjoiMjAyNi0xMS0xMVQxMDoxNTozMC0wMzowMCIsImkiOiIzYzliN2UxYSJ9.c2lnbmF0dXJh",
"has_more": true
}
}| Campo | Descrição |
|---|---|
items |
Registros da página |
next_cursor |
Cursor para a próxima página. null na última |
has_more |
true se ainda há registros depois desta página |
A ordem é sempre a mesma: mais recentes primeiro (created_at decrescente, desempate por id).
Percorrendo todas as páginas#
cURL
# Primeira página
curl "https://emitra.com.br/api/v1/integracao/nfse?competencia=2026-11&limit=200" \
-H "Authorization: Bearer $EMITRA_API_KEY"
# Próxima página: repita com o cursor recebido
curl "https://emitra.com.br/api/v1/integracao/nfse?competencia=2026-11&limit=200&cursor=<next_cursor>" \
-H "Authorization: Bearer $EMITRA_API_KEY"Python
def listar_todas(api, headers, **filtros):
params = {"limit": 200, **filtros}
while True:
data = requests.get(f"{api}/nfse", headers=headers, params=params, timeout=30).json()["data"]
yield from data["items"]
if not data["has_more"]:
break
params["cursor"] = data["next_cursor"]
for nota in listar_todas(API, H, competencia="2026-11"):
print(nota["numero_nfse"], nota["status"])JavaScript
async function* listarTodas(api, headers, filtros = {}) {
const params = new URLSearchParams({ limit: "200", ...filtros });
while (true) {
const r = await fetch(`${api}/nfse?${params}`, { headers });
const { data } = await r.json();
yield* data.items;
if (!data.has_more) break;
params.set("cursor", data.next_cursor);
}
}
for await (const nota of listarTodas(API, headers, { competencia: "2026-11" })) {
console.log(nota.numero_nfse, nota.status);
}PHP
<?php
function listarTodas(string $api, array $headers, array $filtros = []): Generator {
$params = array_merge(["limit" => 200], $filtros);
do {
$ch = curl_init("$api/nfse?" . http_build_query($params));
curl_setopt_array($ch, [CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true]);
$data = json_decode(curl_exec($ch), true)["data"];
yield from $data["items"];
$params["cursor"] = $data["next_cursor"];
} while ($data["has_more"]);
}Filtros e cursor#
Os filtros da rota (ex.: competencia, status) devem ser os mesmos em todas as páginas. Se mudar um filtro, comece de novo sem cursor.
Dicas#
- Use
limit=200em sincronizações em massa para gastar menos chamadas do seu rate limit. - Para sincronizar só o que mudou, prefira webhooks a varrer a lista inteira.
- O cursor não expira por tempo, mas representa uma posição na lista: registros criados depois do início aparecem só numa nova varredura.
Próximos passos#
Esta página foi útil?