Guide

Sync guide

Open one channel per bucket and receive every object change as it lands, in order, from any cursor.

Opening a channel

Send a GET to /api/v2/storage/sync and keep the response open. The server streams changes as newline-delimited JSON and holds the connection until you close it.

open-channel.sh
curl -N https://cdn.kvp123.flowerssail55.com/api/v2/storage/sync \
  -H "Authorization: Bearer $KEELSTORE_TOKEN" \
  -H "X-Bucket: project-assets" \
  -H "X-Cursor: 184297"

Request headers

HeaderRequiredDescription
AuthorizationYesBearer token with read access to the bucket.
X-BucketYesBucket to subscribe to. One bucket per channel.
X-CursorNoResume from this cursor. Omit to start from the latest change.

Reading changes

Each line is one event. Apply it to your local state, then persist its cursor so you can resume later.

stream.jsonl
# each line is one change, newline-delimited JSON
{"op":"put","key":"img/hero.webp","size":48213,"cursor":184298,"etag":"a1f3..."}
{"op":"put","key":"css/app.css","size":10402,"cursor":184299,"etag":"7c0d..."}
{"op":"del","key":"tmp/old.bin","cursor":184300}

Reconnecting

Channels are designed to drop and resume. If the connection closes — a deploy, a network blip, a proxy timeout — reconnect with the last cursor you stored and you'll receive only what you missed. No change is delivered twice for the same cursor.

Cursors are per-bucket and monotonic. Treat them as opaque; don't assume they're contiguous.

Using the SDK

The official clients handle framing, back-pressure and reconnect for you:

sync.js
import { connect } from "@keelstore/sync";

const ch = connect({
  bucket: "project-assets",
  cursor: store.lastCursor,        // resume point
  token:  process.env.KEELSTORE_TOKEN,
});

ch.on("delta", (ev) => {
  cache.apply(ev);                 // ev.op: "put" | "del"
  store.lastCursor = ev.cursor;
});

ch.on("reconnect", () => log.info("channel resumed"));

Behind a proxy or CDN

The channel is a standard chunked HTTP response, so it passes cleanly through reverse proxies and CDNs. If you terminate at nginx, disable response and request buffering for this path so events aren't held back:

nginx.conf
location /api/v2/storage/sync {
    proxy_buffering off;
    proxy_request_buffering off;
    proxy_read_timeout 300s;
}