Change Feed
GET /api/v1/changes is a monotonic, cursor-addressable feed of every create/update
across every resource type. Each event embeds the full resulting record — there is
never a follow-up fetch needed to see what changed.
GET /api/v1/changes?since=<sequence>&limit=<n>[&org=<slug>]
since— resume from this sequence number. Defaults to0(the beginning of the feed) for an initial backfill.limit— page size. Defaults to100, capped at500.org— optional; scopes the feed to one organization by slug. Omit it to see every organization your token has access to. A well-formed but unrecognized slug returns400 { "code": "unknown-org" }.
The response shape is:
{ "events": [/* ChangeEvent[] */], "nextSince": 123 }
Persist nextSince as your cursor and pass it back as since on your next call. If
there are no new events since your last request, the response is { "events": [], "nextSince": <unchanged> } — a stable resume point you can poll against safely.
Ordering and idempotency
- Events are strictly ordered by
sequence; apply them in the order returned. - Applying the same event more than once is safe: key your own storage on
(canonicalId, version)and treat an already-applied version as a no-op. This makes retries, re-polls, and (for webhook consumers) redelivered events all safe to process without special-casing.
Event shape
Every event carries sequence, resourceType, canonicalId, operation ("create"
or "update"), version, occurredAt, orgSlug, and record — the full resource
payload for that resource type (see Data types for every
resource type's field reference, and this site's API reference for the generated
schema). Events also carry sourceSystem, an internal code identifying which upstream
system produced the change; it's most useful for filtering webhook deliveries (see
Webhooks) and can otherwise be ignored.
Worked example
- Poll a page of the change feed, containing one
patientcreation:curl -H "Authorization: Bearer $ROSETTA_SYNC_TOKEN" \"https://sync.example.com/api/v1/changes?since=0&limit=100"{"events": [{"sequence": 1,"resourceType": "patient","canonicalId": "f3024f2e-0583-4759-a9b8-c534e6763391","operation": "create","version": 1,"occurredAt": "2026-07-14T04:32:56.082Z","orgSlug": "default","record": {"identifiers": [{ "system": "urn:michels:pid", "value": "1234567" }],"familyName": "Mueller","givenNames": ["Anna"],"birthDate": "1980-05-01","gender": "female"}}],"nextSince": 1} - Project the event into your own storage: upsert a
patientrow keyed bycanonicalIdwith thisrecordpayload, keyed additionally onversionso a redelivery ofsequence: 1is a no-op. - Advance your cursor: store
nextSince(here,1) and pass it back assinceon your next poll.