Incrementele synchronisatie met updated_since
Om een kopie van de gegevens van Sursa in je eigen systeem bij te houden, hoef je niet elke keer alles te lezen.
De lijsten van objecten met updated_at accepteren updated_since en geven alleen de objecten terug die op of na dat
moment zijn gewijzigd.
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"Met updated_since wordt de lijst oplopend gesorteerd op updated_at en daarna op id, en de
cursor gaat in die volgorde verder. Zo lees je de wijzigingen in de volgorde waarin ze
plaatsvonden, en een paginagrens splitst ze nooit zo dat er een verloren gaat.
updated_since wordt geaccepteerd door deze lijsten:
| Lijst | Wat als wijziging telt |
|---|---|
GET /v1/cards, GET /v1/cards/count | updated_at van de kaart. |
GET /v1/groups | updated_at van de groep: de titel of de instellingen ervan. |
GET /v1/webhooks | updated_at van de webhook: de instellingen en het geheim ervan, niet de leveringen. |
GET /v1/jobs | updated_at van de job: elke wijziging van de status ervan. |
GET /v1/drafts | updated_at van het concept. |
GET /v1/cards/{card_id}/threads | Het laatste moment waarop de eerste opmerking of een antwoord is gemaakt of bewerkt. De thread komt in zijn geheel mee. |
GET /v1/folders, GET /v1/collections/{name}/folders | updated_at van de map. De overeenkomende mappen komen als platte lijst, zie hieronder. |
Collecties, gebruikers en aankondigingen hebben geen updated_at, dus hun lijsten filteren er niet op: ze zijn kort,
lees ze daarom bij elke run in hun geheel. Het tijdstip moet een tijdzoneverschuiving hebben, zoals Z of +02:00;
elke andere waarde wordt geweigerd, net als bij GET /v1/cards.
Met updated_since is een mappenboom geen boom meer: folders van elke collectie bevat de gewijzigde mappen als
platte lijst, met lege children, en parent_id geeft aan waar elke map staat. GET /v1/folders
laat dan de collecties zonder gewijzigde mappen weg.
Een synchronisatielus
- Lees bij de eerste run de hele lijst zonder
updated_sinceen onthoud het moment waarop de run begon. - Geef bij elke volgende run dat onthouden moment mee als
updated_since, min een kleine marge van bijvoorbeeld één minuut, en onthoud het nieuwe begintijdstip. - Schrijf elk object op basis van zijn
idin je opslag en vervang daarbij de vorige kopie. Objecten die door de marge twee keer verschijnen, worden gewoon opnieuw geschreven. - Vraag elke volgende pagina op met de cursor en dezelfde
updated_since. Een cursor werkt alleen met de filters van de eerste pagina: zonder die filters geeft het request400met de codeapi.cursor_invalid.
Doordat je het begintijdstip van de run gebruikt en niet het moment waarop hij klaar was, pakt de volgende run ook een wijziging op die tijdens de lopende run is gemaakt.
GET /v1/cards geeft een JSON-array terug, dus de volgende pagina komt in de header X-Next-Cursor
(zie Lijsten die een array teruggeven):
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
}Verwijderingen
Een lijst geeft alleen objecten terug die bestaan, dus hij kan je niet vertellen dat er iets is verwijderd. Haal verwijderingen uit de eventfeed:
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"Om de feed te lezen heb je een sleutel nodig met de rol admin en de scope webhooks:manage. Events worden 30 dagen bewaard. Heeft je synchronisatie langer dan dat niet gedraaid, lees dan de volledige lijst
opnieuw en verwijder uit je opslag elk object dat er niet meer in staat.
Export naar een datawarehouse brengt lijsten, updated_since en de eventfeed
samen in één proces.