Hopp til innholdet
Sursa Developers

Inkrementell synkronisering med updated_since

For å holde en kopi av Sursa-data i ditt eget system trenger du ikke å lese alt hver gang. Listene over objekter som har updated_at, godtar updated_since og returnerer bare objektene som er endret på eller etter det tidspunktet.

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"

Med updated_since sorteres listen etter updated_at stigende og deretter etter id, og cursoren fortsetter i den rekkefølgen. Dermed leser du endringene i den rekkefølgen de skjedde, og en sidegrense deler dem aldri slik at én av dem går tapt.

updated_since godtas av disse listene:

ListeHva som regnes som en endring
GET /v1/cards, GET /v1/cards/countupdated_at for kortet.
GET /v1/groupsupdated_at for gruppen: tittelen eller innstillingene.
GET /v1/webhooksupdated_at for endepunktet: innstillingene og hemmeligheten, ikke leveransene.
GET /v1/jobsupdated_at for jobben: hver endring av statusen.
GET /v1/draftsupdated_at for utkastet.
GET /v1/cards/{card_id}/threadsSiste gang rotkommentaren eller et av svarene ble opprettet eller redigert. Tråden kommer i sin helhet.
GET /v1/folders, GET /v1/collections/{name}/foldersupdated_at for mappen. Mappene som oppfyller filteret, kommer som en flat liste, se nedenfor.

Samlinger, brukere og kunngjøringer har ikke updated_at, så listene deres filtrerer ikke etter det: De er korte, så les dem i sin helhet ved hver kjøring. Tidspunktet må ha en forskyvning for tidssonen, for eksempel Z eller +02:00; alle andre verdier avvises, som med GET /v1/cards.

Med updated_since er et mappetre ikke lenger et tre: folders for hver samling inneholder de endrede mappene som en flat liste, med tom children, og parent_id viser hvor hver av dem ligger. GET /v1/folders utelater da samlingene uten endrede mapper.

En synkroniseringsløkke

  1. Les hele listen uten updated_since ved første kjøring, og husk tidspunktet da kjøringen startet.
  2. Send det lagrede tidspunktet som updated_since ved hver neste kjøring, minus en liten margin, for eksempel ett minutt, og husk det nye starttidspunktet.
  3. Skriv hvert objekt til lageret ditt etter id, slik at den forrige kopien erstattes. Objekter som dukker opp to ganger på grunn av marginen, blir ganske enkelt skrevet på nytt.
  4. Be om hver neste side med cursoren og den samme updated_since. En cursor virker bare med filtrene fra den første siden: Uten dem returnerer forespørselen 400 med koden api.cursor_invalid.

Når du bruker starttidspunktet for kjøringen og ikke tidspunktet den ble ferdig, fanges en endring som gjøres mens kjøringen pågår, opp av den neste kjøringen.

GET /v1/cards returnerer et JSON-array, så neste side kommer i headeren X-Next-Cursor (se Lister som returnerer et array):

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
}

Slettinger

En liste returnerer bare objekter som finnes, så den kan ikke fortelle deg at noe er slettet. Hent slettinger fra hendelsesfeeden:

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"

For å lese feeden trenger du en nøkkel med rollen admin og scopet webhooks:manage. Hendelser lagres i 30 dager. Hvis synkroniseringen din ikke har kjørt på lengre tid enn det, leser du hele listen på nytt og fjerner fra lageret ditt alle objekter som ikke lenger er med i den.

Veiledningen Eksporter til et datavarehus samler lister, updated_since og hendelsesfeeden i én jobb.