Paginazione
Gli elenchi dell’API di Sursa sono paginati con un cursore: chiedi fino a limit elementi e la risposta ti dice
come ottenere la pagina successiva. Non calcoli mai offset, e gli elementi non si ripetono né mancano tra una pagina e
l’altra quando i dati cambiano nel frattempo.
| Parametro | Valore |
|---|---|
limit | Quanti elementi per pagina, di solito da 1 a 200. Gli elenchi nuovi hanno il valore predefinito 50; il riferimento mostra l’intervallo e il valore predefinito di ogni elenco. |
cursor | Il cursore della pagina precedente. Omettilo per la prima pagina. |
Un elenco restituisce il cursore successivo in uno di due modi, a seconda della forma della sua risposta. La pagina di ogni endpoint nel riferimento API mostra quale usa.
Elenchi con il contenitore data
Gli elenchi aggiunti per l’API pubblica, come il feed degli eventi, restituiscono un oggetto con gli elementi in data:
curl "https://api.sursa.com/v1/webhook-events?limit=2" \
-H "Authorization: Bearer $SURSA_API_KEY"{
"data": [
{"id": "evt_8a1f…", "type": "card.published", "created_at": "2026-10-24T10:00:00Z"},
{"id": "evt_8a20…", "type": "card.updated", "created_at": "2026-10-24T10:00:03Z"}
],
"next_cursor": "eyJ2IjoxLCJrIjpbMTA0Ml19",
"has_more": true
}
Quando has_more è true, richiedi la pagina successiva con cursor impostato su next_cursor e gli stessi
filtri:
curl "https://api.sursa.com/v1/webhook-events?limit=2&cursor=eyJ2IjoxLCJrIjpbMTA0Ml19" \
-H "Authorization: Bearer $SURSA_API_KEY"Gli elenchi che esistevano prima dei cursori e restituiscono un oggetto mantengono un contenitore proprio (per esempio
{"items": […], "total": 120}). Ricevono next_cursor e has_more nello stesso oggetto; gli elementi restano dove
erano.
Elenchi che restituiscono un array
Alcuni elenchi restituiscono un array JSON semplice, per esempio GET /v1/collections.
La forma della loro risposta non può cambiare, quindi la pagina successiva arriva invece nelle intestazioni:
curl -i "https://api.sursa.com/v1/collections?limit=50" \
-H "Authorization: Bearer $SURSA_API_KEY"HTTP/1.1 200 OK
Link: <https://api.example.com/v1/collections?limit=50&cursor=eyJ2IjoxLCJrIjpbNTBdfQ>; rel="next"
X-Next-Cursor: eyJ2IjoxLCJrIjpbNTBdfQ
[{"id": 1, "name": "support", …}, …]
Linkconrel="next"è l’indirizzo completo della pagina successiva;X-Next-Cursorè lo stesso cursore da solo.- Nessun
Linkconrel="next"e nessunX-Next-Cursorsignifica che questa è l’ultima pagina. - Senza
limit, questi elenchi restituiscono tutti gli elementi in una sola risposta, come hanno sempre fatto. Passalimitper paginarli; il cursore ricorda la dimensione della pagina, quindi la richiesta successiva può ometterelimit. GET /v1/cardsè l’eccezione: restituisce sempre pagine, 200 schede per impostazione predefinita e fino a 1000 conlimit, quindi seguiX-Next-Cursoranche senzalimit.
// Every item of a list that returns an array.
async function* listArray(path) {
let next = `https://api.sursa.com${path}?limit=200`;
while (next) {
const response = await fetch(next, { headers: { Authorization: `Bearer ${process.env.SURSA_API_KEY}` } });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
yield* await response.json();
const cursor = response.headers.get("X-Next-Cursor");
next = cursor ? `https://api.sursa.com${path}?cursor=${encodeURIComponent(cursor)}` : null;
}
}Il feed degli eventi
Il feed degli eventi GET /v1/webhook-events è un registro, quindi la sua
paginazione è un po’ diversa:
- Gli eventi sono in ordine crescente, dal più vecchio.
next_cursorviene restituito in ogni pagina, anche quandohas_moreèfalse. Conservalo e richiedi più tardi con lo stesso cursore per ottenere gli eventi avvenuti nel frattempo. Il feed è una coda che puoi leggere al tuo ritmo.- Un evento compare nel feed entro circa un secondo dalla modifica che descrive, e mai prima di un evento già letto.
- Il feed contiene gli eventi dell’intera organizzazione, quindi per leggerlo serve una chiave con il ruolo
admine l’ambitowebhooks:manage.
Esportare in un data warehouse mostra un ciclo di polling completo.
Regole per i cursori
- Un cursore è una stringa opaca di massimo 512 caratteri. Non analizzarla e non costruirla da solo: il suo formato può cambiare.
- Un cursore appartiene a un solo elenco e a un solo insieme di filtri. Un cursore danneggiato, proveniente da un altro
elenco o inviato con filtri diversi restituisce
400con il codiceapi.cursor_invalid. - Ogni elenco ha un ordinamento fisso che termina con una chiave univoca, quindi ogni elemento compare esattamente in una pagina.
- Gli elenchi aggiunti con i cursori non restituiscono un conteggio totale; gli elenchi che avevano già un
totallo mantengono. Se ti serve un totale, conta gli elementi man mano.
Paginazione per offset
Alcuni elenchi accettavano offset prima che venissero introdotti i cursori, e lo accettano ancora, così le
integrazioni esistenti continuano a funzionare. Nel codice nuovo preferisci cursor. offset e cursor non si
possono combinare: inviarli entrambi restituisce 422 con il codice validation.failed.