Chuyển tới nội dung
Sursa Developers

Đồng bộ gia tăng với updated_since

Để giữ một bản sao dữ liệu Sursa trong hệ thống của bạn, bạn không cần đọc mọi thứ mỗi lần. Danh sách các đối tượng có updated_at chấp nhận updated_since và chỉ trả về những đối tượng đã thay đổi tại hoặc sau thời điểm đó.

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"

Với updated_since, danh sách được sắp xếp theo updated_at tăng dần, rồi theo id, và con trỏ tiếp tục theo thứ tự đó. Nhờ vậy bạn đọc các thay đổi theo đúng thứ tự chúng xảy ra, và ranh giới giữa các trang không bao giờ chia cắt chúng theo cách làm mất một thay đổi nào.

updated_since được chấp nhận trong các danh sách sau:

Danh sáchĐiều gì được tính là thay đổi
GET /v1/cards, GET /v1/cards/countupdated_at của thẻ.
GET /v1/groupsupdated_at của nhóm: tiêu đề hoặc cài đặt của nhóm.
GET /v1/webhooksupdated_at của webhook: cài đặt và khóa bí mật của nó, không phải các lần gửi.
GET /v1/jobsupdated_at của tác vụ: mọi thay đổi trạng thái của nó.
GET /v1/draftsupdated_at của bản nháp.
GET /v1/cards/{card_id}/threadsLần tạo hoặc chỉnh sửa gần nhất của bình luận gốc hoặc của bất kỳ trả lời bình luận nào. Chuỗi bình luận được trả về đầy đủ.
GET /v1/folders, GET /v1/collections/{name}/foldersupdated_at của thư mục. Các thư mục khớp được trả về dưới dạng danh sách phẳng, xem bên dưới.

Bộ sưu tập, người dùng và thông báo không có updated_at, nên danh sách của chúng không lọc theo trường này: các danh sách này ngắn, nên hãy đọc toàn bộ ở mỗi lần chạy. Thời điểm phải có độ lệch múi giờ, chẳng hạn Z hoặc +02:00; mọi giá trị khác đều bị từ chối, như với GET /v1/cards.

Với updated_since, cây thư mục không còn là cây: folders của mỗi bộ sưu tập chứa các thư mục đã thay đổi dưới dạng danh sách phẳng, với children trống, và parent_id cho biết vị trí của từng thư mục. Khi đó GET /v1/folders bỏ qua các bộ sưu tập không có thư mục nào thay đổi.

Vòng lặp đồng bộ

  1. Ở lần chạy đầu tiên, đọc toàn bộ danh sách mà không có updated_since, và ghi nhớ thời điểm lần chạy bắt đầu.
  2. Ở mỗi lần chạy tiếp theo, truyền thời điểm đã ghi nhớ đó làm updated_since, trừ đi một khoảng dự phòng nhỏ, chẳng hạn một phút, và ghi nhớ thời điểm bắt đầu mới.
  3. Ghi từng đối tượng vào kho của bạn theo id, thay thế bản sao trước đó. Những đối tượng xuất hiện hai lần do khoảng dự phòng chỉ đơn giản được ghi lại.
  4. Yêu cầu mỗi trang tiếp theo bằng con trỏ và cùng giá trị updated_since. Con trỏ chỉ hoạt động với các bộ lọc của trang đầu tiên: thiếu chúng, yêu cầu trả về 400 với mã api.cursor_invalid.

Dùng thời điểm bắt đầu của lần chạy, chứ không phải thời điểm kết thúc, bảo đảm rằng thay đổi xảy ra trong khi lần chạy đang diễn ra sẽ được lần chạy sau lấy về.

GET /v1/cards trả về một mảng JSON, nên trang tiếp theo của nó nằm trong header X-Next-Cursor (xem Danh sách trả về mảng):

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
}

Thao tác xóa

Danh sách chỉ trả về những đối tượng đang tồn tại, nên nó không thể cho bạn biết thứ gì đã bị xóa. Hãy lấy các thao tác xóa từ nguồn cấp sự kiện:

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"

Để đọc nguồn cấp, bạn cần một khóa có vai trò admin và phạm vi webhooks:manage. Sự kiện được lưu giữ trong 30 ngày. Nếu quá trình đồng bộ của bạn không chạy lâu hơn khoảng đó, hãy đọc lại toàn bộ danh sách và xóa khỏi kho của bạn mọi đối tượng không còn trong đó.

Xuất sang kho dữ liệu kết hợp danh sách, updated_since và nguồn cấp sự kiện trong một tác vụ.