Anar al contingut
Sursa Developers

Sincronització incremental amb updated_since

Per mantenir una còpia de les dades de Sursa al vostre propi sistema, no cal llegir-ho tot cada vegada. Les llistes d’objectes que tenen updated_at accepten updated_since i només retornen els objectes que han canviat en aquell moment o després.

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"

Amb updated_since, la llista s’ordena per updated_at en ordre ascendent i després per id, i el cursor continua en aquest ordre. Així, llegiu els canvis en l’ordre en què s’han produït, i un límit de pàgina no els separa mai de manera que se’n perdi cap.

Accepten updated_since aquestes llistes:

LlistaQuè compta com a canvi
GET /v1/cards, GET /v1/cards/countEl updated_at de l’entrada.
GET /v1/groupsEl updated_at del grup: el títol o la configuració.
GET /v1/webhooksEl updated_at del webhook: la configuració i el secret, no els lliuraments.
GET /v1/jobsEl updated_at del treball: cada canvi del seu estat.
GET /v1/draftsEl updated_at de l’esborrany.
GET /v1/cards/{card_id}/threadsLa creació o edició més recent del comentari arrel o de qualsevol resposta. El fil arriba sencer.
GET /v1/folders, GET /v1/collections/{name}/foldersEl updated_at de la carpeta. Les carpetes que coincideixen arriben com una llista plana; vegeu més avall.

Les col·leccions, els usuaris i els avisos no tenen updated_at, de manera que les seves llistes no hi filtren: són curtes, així que llegiu-les senceres a cada execució. El moment ha de tenir un desplaçament de fus horari, com ara Z o +02:00; qualsevol altre valor es rebutja, com a GET /v1/cards.

Amb updated_since, un arbre de carpetes deixa de ser un arbre: el folders de cada col·lecció conté les carpetes que han canviat en una llista plana, amb children buit, i parent_id indica on és cadascuna. Aleshores GET /v1/folders omet les col·leccions sense carpetes que hagin canviat.

Un bucle de sincronització

  1. A la primera execució, llegiu tota la llista sense updated_since i recordeu el moment en què ha començat l’execució.
  2. A cada execució següent, passeu aquest moment com a updated_since, menys un petit marge, com ara un minut, i recordeu la nova hora d’inici.
  3. Escriviu cada objecte al vostre magatzem pel seu id, substituint la còpia anterior. Els objectes que apareixen dues vegades a causa del marge simplement es tornen a escriure.
  4. Demaneu cada pàgina següent amb el cursor i el mateix updated_since. Un cursor només funciona amb els filtres de la primera pàgina: sense aquests filtres, la sol·licitud retorna 400 amb el codi api.cursor_invalid.

Fer servir l’hora d’inici de l’execució, i no la d’acabament, garanteix que l’execució següent reculli qualsevol canvi fet mentre l’execució estava en curs.

GET /v1/cards retorna una matriu JSON, de manera que la seva pàgina següent arriba a la capçalera X-Next-Cursor (vegeu Llistes que retornen una matriu):

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
}

Eliminacions

Una llista només retorna objectes que existeixen, per això no us pot dir que s’ha eliminat alguna cosa. Preneu les eliminacions del canal d’esdeveniments:

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"

Per llegir el canal cal una clau amb el rol admin i l’àmbit webhooks:manage. Els esdeveniments es conserven durant 30 dies. Si la vostra sincronització no s’ha executat durant més temps, torneu a llegir tota la llista i elimineu del vostre magatzem tots els objectes que ja no hi siguin.

La guia Exportar a un magatzem de dades reuneix les llistes, updated_since i el canal d’esdeveniments en un sol treball.