Пређите на садржај
Sursa Developers

Инкрементална синхронизација помоћу updated_since

Да бисте у свом систему чували копију података из платформе Sursa, не морате сваки пут да читате све. Листе објеката који имају updated_at прихватају updated_since и враћају само објекте измењене у том тренутку или после њега.

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"

Уз updated_since листа је сортирана по updated_at растуће, затим по id, а курсор наставља тим редоследом. Тако измене читате редоследом којим су се десиле, а граница странице их никада не дели тако да се нека изгуби.

updated_since прихватају следеће листе:

ЛистаШта се рачуна као измена
GET /v1/cards, GET /v1/cards/countupdated_at картице.
GET /v1/groupsupdated_at групе: њен наслов или подешавања.
GET /v1/webhooksupdated_at вебхука: његова подешавања и тајна, не његове испоруке.
GET /v1/jobsupdated_at посла: свака промена његовог статуса.
GET /v1/draftsupdated_at нацрта.
GET /v1/cards/{card_id}/threadsПоследње креирање или измена основног коментара или било ког одговора. Нит стиже цела.
GET /v1/folders, GET /v1/collections/{name}/foldersupdated_at фолдера. Фолдери који се поклапају стижу као равна листа, в. у наставку.

Колекције, корисници и обавештења немају updated_at, па њихове листе не филтрирају по њему: кратке су, па их при сваком покретању прочитајте целе. Време мора да садржи помак временске зоне, на пример Z или +02:00; свака друга вредност се одбија, као и код GET /v1/cards.

Уз updated_since стабло фолдера више није стабло: folders сваке колекције садржи измењене фолдере као равну листу, са празним children, а parent_id показује где се сваки од њих налази. GET /v1/folders тада изоставља колекције без измењених фолдера.

Петља синхронизације

  1. При првом покретању прочитајте целу листу без updated_since и запамтите тренутак када је покретање почело.
  2. При сваком следећем покретању проследите тај запамћени тренутак као updated_since, умањен за малу резерву, на пример један минут, и запамтите ново време почетка.
  3. Сваки објекат упишите у своје складиште по његовом id, уместо претходне копије. Објекти који се због резерве појаве двапут једноставно се поново упишу.
  4. Сваку следећу страницу затражите са курсором и истим updated_since. Курсор ради само са филтерима прве странице: без њих захтев враћа 400 са кодом api.cursor_invalid.

Пошто се узима време почетка покретања, а не време завршетка, измену направљену док покретање траје преузеће следеће покретање.

GET /v1/cards враћа JSON низ, па његова следећа страница стиже у заглављу X-Next-Cursor (погледајте Листе које враћају низ):

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
}

Брисања

Листа враћа само објекте који постоје, па не може да вам каже да је нешто обрисано. Брисања преузмите из фида догађаја:

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"

За читање фида потребан је кључ са улогом admin и опсегом webhooks:manage. Догађаји се чувају 30 дана. Ако ваша синхронизација није радила дуже од тога, поново прочитајте целу листу и из свог складишта уклоните сваки објекат којег у њој више нема.

Извоз у складиште података обједињује листе, updated_since и фид догађаја у једном решењу.