Paginação
Cursor por data em GET /scans: limit, before e next_before.
Só GET /scans é paginado. GET /apps não precisa: o número de apps é limitado pelo plano e cabe numa resposta.
Como funciona
Cursor por data, não por offset: o histórico recebe rondas novas no topo o tempo todo, e com offset uma ronda disparada no meio da paginação empurraria a lista e você leria o mesmo registro duas vezes.
| Parâmetro | Descrição |
|---|---|
limitintegerpadrão: 20 | Rondas por página. Teto 50 (valores acima são reduzidos a 50; ausente, inválido ou ≤ 0 cai no padrão). |
beforestring | Cursor: só rondas criadas ANTES deste instante (exclusivo). Use o next_before da página anterior. Data não-ISO responde 400 invalid_cursor. |
A resposta traz next_before: o created_at do último item da página. Mande esse valor em before pra pegar a próxima. O cursor é exclusivo (created_at < before), então a ronda que fechou a página anterior não repete.
{
"data": [
{
"id": "scan_7b3e9a12",
"hostname": "app.exemplo.com.br",
"status": "done",
"created_at": "2026-08-27T14:02:56.902Z",
"finished_at": "2026-08-27T14:09:24.106Z",
"risk_score": 78,
"risk_label": "HIGH_RISK",
"critical_count": 2,
"blocked": false
},
{
"id": "scan_1c40de55",
"hostname": "staging.exemplo.com.br",
"status": "done",
"created_at": "2026-08-21T11:15:03.517Z",
"finished_at": "2026-08-21T11:19:42.204Z",
"risk_score": 34,
"risk_label": "MODERATE_RISK",
"critical_count": 0,
"blocked": false
}
],
"next_before": "2026-08-21T11:15:03.517Z"
}curl "https://api.guarita.dev/v1/public/scans?limit=2&before=2026-08-21T11:15:03.517Z" \
-H "Authorization: Bearer $GUARITA_API_KEY"Percorrer o histórico
// Percorre o histórico inteiro, página por página.
async function todasAsRondas() {
const rondas = [];
let before = null;
for (;;) {
const url = new URL("https://api.guarita.dev/v1/public/scans");
url.searchParams.set("limit", "50");
if (before) url.searchParams.set("before", before);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.GUARITA_API_KEY}` },
});
if (!res.ok) throw new Error(`Guarita ${res.status}: ${await res.text()}`);
const { data, next_before } = await res.json();
rondas.push(...data);
if (!next_before) return rondas; // acabou — pare AQUI, não em data.length < limit
before = next_before;
}
}Casos de borda
next_before vem preenchido sempre que a página veio cheia — inclusive quando o total é múltiplo exato do limit. Nesse caso a chamada seguinte devolve data: [] e next_before: null. Um laço que para em data.length < limit pode parar cedo demais.before que não é data ISO 8601 responde 400 invalid_cursor. limit acima de 50 vira 50; ausente ou inválido vira 20.
O histórico respeita a retenção do plano (Pro: 365 dias · Business: sem limite). Rondas mais antigas não estão numa página seguinte — não existem mais.
x-request-id, se for sobre uma resposta.