Salt la conținut
Sursa Developers

Paginare

Listele API-ului Sursa sunt paginate cu un cursor: cereți cel mult limit elemente, iar răspunsul vă spune cum obțineți pagina următoare. Nu calculați niciodată decalaje, iar elementele nu se repetă și nu lipsesc între pagini dacă datele se schimbă între timp.

ParametruValoare
limitCâte elemente pe pagină, de obicei între 1 și 200. Listele noi au implicit 50; referința arată intervalul și valoarea implicită a fiecărei liste.
cursorCursorul de la pagina anterioară. Omiteți-l pentru prima pagină.

O listă returnează cursorul următor în unul dintre două moduri, în funcție de forma răspunsului ei. Pagina fiecărui endpoint din referința API arată care mod este folosit.

Liste cu plicul data

Listele adăugate pentru API-ul public, de exemplu fluxul de evenimente, returnează un obiect cu elementele în 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
}

Când has_more este true, cereți pagina următoare cu cursor setat la next_cursor și cu aceleași filtre:

curl "https://api.sursa.com/v1/webhook-events?limit=2&cursor=eyJ2IjoxLCJrIjpbMTA0Ml19" \
  -H "Authorization: Bearer $SURSA_API_KEY"

Listele care existau înainte de cursoare și returnează un obiect își păstrează propriul plic (de exemplu {"items": […], "total": 120}). Ele primesc next_cursor și has_more în același obiect; elementele rămân unde erau.

Liste care returnează un tablou

Câteva liste returnează un tablou JSON simplu, de exemplu GET /v1/collections. Forma răspunsului lor nu se poate schimba, așa că pagina următoare vine în antete:

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", …}, …]
  • Link cu rel="next" este adresa completă a paginii următoare; X-Next-Cursor este același cursor, separat.
  • Dacă nu există Link cu rel="next" și nici X-Next-Cursor, aceasta este ultima pagină.
  • Fără limit, aceste liste returnează toate elementele într-un singur răspuns, ca întotdeauna. Transmiteți limit pentru a le pagina; cursorul reține dimensiunea paginii, așa că următoarea cerere poate omite limit.
  • GET /v1/cards este excepția: returnează mereu pagini, implicit 200 de fișe și cel mult 1000 cu limit, așa că urmați X-Next-Cursor chiar și fără limit.
// 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;
  }
}

Fluxul de evenimente

Fluxul de evenimente GET /v1/webhook-events este un jurnal, așa că se paginează puțin diferit:

  • Evenimentele sunt în ordine crescătoare, cele mai vechi primele.
  • next_cursor este returnat pe fiecare pagină, chiar și când has_more este false. Stocați-l și cereți din nou mai târziu cu același cursor, pentru a primi evenimentele produse între timp. Fluxul este o coadă pe care o puteți citi în ritmul propriu.
  • Un eveniment apare în flux la circa o secundă după modificarea pe care o descrie și niciodată înaintea unui eveniment care a fost deja citit.
  • Fluxul conține evenimentele întregii organizații, de aceea citirea lui necesită o cheie cu rolul admin și domeniul webhooks:manage.

Exportul într-un depozit de date arată o buclă completă de interogare periodică.

Reguli pentru cursoare

  • Un cursor este un șir opac de cel mult 512 caractere. Nu îl analizați și nu îl construiți singuri: formatul lui se poate schimba.
  • Un cursor aparține unei singure liste și unui singur set de filtre. Un cursor deteriorat, provenit din altă listă sau trimis cu alte filtre returnează 400 cu codul api.cursor_invalid.
  • Fiecare listă are o ordine de sortare fixă, care se termină cu o cheie unică, așa că fiecare element apare pe exact o pagină.
  • Listele adăugate cu cursoare nu returnează un număr total; listele care aveau înainte total îl păstrează. Numărați elementele pe parcurs dacă aveți nevoie de un total.

Paginare prin decalaj (offset)

Unele liste acceptau offset înainte de introducerea cursoarelor și îl acceptă în continuare, ca integrările existente să funcționeze mai departe. În codul nou preferați cursor. offset și cursor nu pot fi combinate: dacă le trimiteți pe amândouă, primiți 422 cu codul validation.failed.