Paginação e filtros¶
Para: Dev — Conferido em 2026-10-18.
Toda listagem da API devolve {"data": [...], "next_cursor": ...}. Esta página mostra, endpoint por endpoint, o nome
do parâmetro de cursor, em que ordem os itens saem, quais filtros existem e como percorrer uma lista inteira sem pular
nem repetir itens.
O que é¶
A paginação é por cursor, nunca por número de página. Cada resposta traz até limit itens e um next_cursor:
next_cursorcom valor: existe pelo menos mais um item; mande esse valor no parâmetro de cursor da próxima chamada;next_cursorigual anull: acabou. A API só devolve cursor quando há, de fato, mais um item, então não existe "última página vazia".
| Parâmetro | Regra |
|---|---|
limit |
Inteiro de 1 a 200. Padrão 50. Fora da faixa, 400 validation_failed. |
| cursor | Texto devolvido em next_cursor. O nome do parâmetro muda por endpoint (tabela abaixo). Cursor inválido: 400 validation_failed com reason: format. |
Quando usar¶
- Recuperar um
POSTperdido:GET /deposits?external_id=…ouGET /withdrawals?external_id=…(uma página basta). - Varrer um período:
updated_sincecomlimit=200, para conciliação ou para reconstruir um estado perdido. - Seguir o que aconteceu:
GET /eventscom o cursorafter, que é a ferramenta de recuperação de webhooks (Recuperação porGET /events). - Estado de rotina de um objeto: não liste. Use
GET /deposits/{id}ouGET /withdrawals/{id}, que têm balde de limite maior (Limites e quotas).
Como funciona¶
Cursor, ordem e filtros por endpoint¶
| Endpoint | Parâmetro do cursor | O que é o cursor | Ordem dos itens | Filtros |
|---|---|---|---|---|
GET /deposits |
cursor |
o id (dep_…) do último item recebido |
por id, que acompanha a ordem de criação |
external_id, player_ref, status, updated_since, limit |
GET /withdrawals |
cursor |
texto opaco | por data de criação e, no empate, por id |
external_id, player_ref, status, updated_since, limit |
GET /events |
after |
o id (evt_…) do último evento recebido |
por criação do evento | object_id, limit |
GET /reconciliation |
cursor |
texto opaco | por object_id e, no empate, por kind |
date e currency (obrigatórios), limit |
GET /receipts |
cursor |
nunca devolvido | sempre vazio | status, updated_since, limit |
Pontos de atenção:
- Não ordena por
updated_at.GET /depositssai em ordem de criação, e um depósito atualizado agora continua na posição em que nasceu. Para achar o que mudou, filtre porupdated_since. - Cursor opaco é opaco. O cursor de
/withdrawalse o de/reconciliationsão texto que só o Dracma interpreta: não construa, não edite, não ordene e não guarde por mais tempo que a varredura. O formato pode mudar sem aviso. O cursor de/depositse/eventsé umidque você já viu; mesmo assim, use sempre o valor denext_cursor. - Cursor serve só para o mesmo conjunto de filtros. Mudou um filtro no meio da varredura: recomece sem cursor.
GET /eventscomafterde outra operação ou que não existe volta400comreason: unknown(a API não confirma se o evento existe em outra operação).GET /receiptsdevolve sempre{"data": [], "next_cursor": null}e valida os parâmetros; qualquercursorenviado volta400(reason: format), porque a API nunca emite cursor de recebimento (Rotas e campos reservados).GET /reconciliationdevolve os itens do dia em páginas; os totais, o digest e a assinatura (cabeçalhoDracma-Signature) vêm na última página, a que temnext_cursornull(Reconciliação).
updated_since¶
updated_since é um instante RFC 3339 (2026-10-18T12:00:00Z; aceita fração de segundo) e filtra por
updated_at >= updated_since: maior ou igual, inclusive. Por isso o item exatamente na borda reaparece. Para uma
varredura incremental:
- guarde o maior
updated_atque você viu (T) e aversionde cada objeto; - na próxima rodada, chame com
updated_since=T; - descarte o que você já tem com a mesma
version(aversionsobe a cada transição); - nunca avance
Talém do maiorupdated_atrealmente lido.
O mais robusto para acompanhar mudanças é o webhook mais o GET /events; updated_since é para conferência.
Percorrer tudo¶
cursor = vazio
repita:
resposta = GET /v1/deposits?updated_since=T&limit=200 (+ &cursor=<cursor> se houver)
processe(resposta.data)
se resposta.next_cursor é null: pare
cursor = resposta.next_cursor
espere pelo menos 200 ms entre páginas # a listagem tem balde próprio de 5 req/s
Cada página é uma requisição assinada nova (novo timestamp e nonce). O Retry-After do 429 diz quanto esperar; repita a
mesma página, com o mesmo cursor.
Exemplos¶
Primeira página de saques, e a seguinte. O caminho assinado inclui a query exatamente como enviada (Autenticação HMAC):
GET /v1/withdrawals?status=processing&limit=2
→ 200 {"data":[{...},{...}],"next_cursor":"<texto opaco>"}
GET /v1/withdrawals?status=processing&limit=2&cursor=<texto opaco>
→ 200 {"data":[{...}],"next_cursor":null}
Eventos a partir do último que você processou:
GET /v1/events?after=evt_<último id processado>&limit=100
→ 200 {"data":[ ...eventos... ],"next_cursor":"evt_<id do último desta página>"}
Consulta de um depósito pelo seu external_id (recuperação de POST perdido):
GET /v1/deposits?external_id=dep_0192a3b4-5c6d-7e8f-9a0b-1c2d3e4f5a6b
→ 200 {"data":[{...}],"next_cursor":null}
Erros e casos de borda¶
| Situação | Resposta |
|---|---|
limit=0, limit=201 ou limit=abc |
400 validation_failed (field: limit) |
cursor que o Dracma nunca emitiu, ou adulterado |
400 validation_failed (field: cursor, reason: format) |
status desconhecido |
400 validation_failed (field: status) |
updated_since fora de RFC 3339 |
400 validation_failed (field: updated_since, reason: format) |
after de GET /events que não existe nesta operação |
400 validation_failed (field: after, reason: unknown) |
| Filtro sem resultado | 200 com "data": [] e "next_cursor": null |
| Muitas páginas por segundo | 429 rate_limited; a listagem tem balde próprio de 5 req/s por chave |
| Objeto criado durante a varredura | Pode ou não aparecer, conforme a ordem; a próxima rodada com updated_since o pega |
Mudar o limit no meio da varredura é permitido: o cursor não depende dele.