Ugrás a tartalomra
Sursa Developers

Növekményes szinkronizálás az updated_since paraméterrel

Ha a Sursa adatainak másolatát a saját rendszeredben tartod, nem kell minden alkalommal mindent beolvasnod. Az updated_at mezővel rendelkező objektumok listái elfogadják az updated_since paramétert, és csak azokat az objektumokat adják vissza, amelyek az adott pillanatban vagy azután változtak.

curl -G https://api.sursa.com/v1/cards \
  -H "Authorization: Bearer $SURSA_API_KEY" \
  --data-urlencode "updated_since=2026-10-23T00:00:00Z" \
  --data-urlencode "limit=200"

Az updated_since paraméterrel a lista updated_at szerint növekvő sorrendbe rendeződik, azon belül id szerint, és a kurzor ebben a sorrendben halad tovább. Így a változásokat abban a sorrendben olvasod be, ahogy történtek, és az oldalhatár soha nem vágja el őket úgy, hogy egy elvesszen.

Az updated_since paramétert ezek a listák fogadják el:

ListaMi számít változásnak
GET /v1/cards, GET /v1/cards/countA kártya updated_at mezője.
GET /v1/groupsA csoport updated_at mezője: a címe vagy a beállításai.
GET /v1/webhooksA webhook updated_at mezője: a beállításai és a titkos kulcsa, a kézbesítései nem.
GET /v1/jobsA feladat updated_at mezője: az állapotának minden változása.
GET /v1/draftsA piszkozat updated_at mezője.
GET /v1/cards/{card_id}/threadsA fő hozzászólás vagy bármely válasz legutóbbi létrehozása vagy szerkesztése. A szál teljes egészében érkezik.
GET /v1/folders, GET /v1/collections/{name}/foldersA mappa updated_at mezője. Az egyező mappák lapos listaként érkeznek, lásd lent.

A gyűjteményeknek, a felhasználóknak és a közleményeknek nincs updated_at mezőjük, ezért a listáik nem szűrnek szerinte: ezek rövidek, így minden futáskor olvasd be őket teljes egészében. Az időpontnak időzóna-eltolást kell tartalmaznia, például Z vagy +02:00 értéket; minden más értéket a Sursa elutasít, mint a GET /v1/cards esetén.

Az updated_since paraméterrel a mappafa már nem fa: minden gyűjtemény folders mezője lapos listaként tartalmazza a megváltozott mappákat, üres children mezővel, a parent_id pedig megmutatja, hol helyezkedik el az egyes mappa. A GET /v1/folders ilyenkor kihagyja azokat a gyűjteményeket, amelyekben nincs megváltozott mappa.

Szinkronizálási ciklus

  1. Az első futáskor olvasd be a teljes listát updated_since nélkül, és jegyezd meg, mikor indult a futás.
  2. Minden további futáskor add meg ezt a megjegyzett pillanatot updated_since értékként, egy kis ráhagyással, például egy perccel korábbra véve, és jegyezd meg az új kezdési időt.
  3. Minden objektumot az id mezője szerint írj be a tárodba, lecserélve az előző másolatot. A ráhagyás miatt kétszer megjelenő objektumok egyszerűen újra beíródnak.
  4. Minden következő oldalt a kurzorral és ugyanazzal az updated_since értékkel kérj le. A kurzor csak az első oldal szűrőivel működik: nélkülük a válasz 400 az api.cursor_invalid kóddal.

Ha a futás kezdési idejét használod, nem pedig a befejezését, a futás közben végrehajtott változtatást a következő futás biztosan átveszi.

A GET /v1/cards JSON-tömböt ad vissza, ezért a következő oldala az X-Next-Cursor fejlécben érkezik (lásd: Tömböt visszaadó listák):

const BASE = "https://api.sursa.com";
const headers = { Authorization: `Bearer ${process.env.SURSA_API_KEY}` };

async function syncCards(since, saveCard) {
  const startedAt = new Date();
  const params = new URLSearchParams({ limit: "200" });
  if (since) params.set("updated_since", new Date(since.getTime() - 60_000).toISOString());
  let query = params.toString();
  while (query) {
    const response = await fetch(`${BASE}/v1/cards?${query}`, { headers });
    if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
    for (const card of await response.json()) await saveCard(card); // write into your store by card.id
    const cursor = response.headers.get("X-Next-Cursor");
    if (cursor) params.set("cursor", cursor); // keep updated_since: the cursor needs the same filters
    query = cursor ? params.toString() : "";
  }
  return startedAt; // pass it as `since` next time
}

Törlések

A lista csak a létező objektumokat adja vissza, ezért nem tudja jelezni, hogy valamit töröltek. A törléseket az eseménycsatornából vedd át:

curl -G https://api.sursa.com/v1/webhook-events \
  -H "Authorization: Bearer $SURSA_API_KEY" \
  --data-urlencode "type=card.deleted" \
  --data-urlencode "created_since=2026-10-23T00:00:00Z"

A csatorna olvasásához admin szerepkörű és webhooks:manage hatókörű kulcs kell. Az eseményeket a Sursa 30 napig őrzi meg. Ha a szinkronizálásod ennél régebben nem futott, olvasd be újra a teljes listát, és távolíts el a tárodból minden olyan objektumot, amely már nincs benne.

Az Exportálás adattárházba útmutató a listákat, az updated_since paramétert és az eseménycsatornát egyetlen feladatba foglalja.