Skip to main content
GET /v4/changes is the organization’s change feed. Store the cursor you last read and resume from it; the feed never reorders behind a cursor, so a resumed read misses nothing. The changes.available webhook only wakes you up — replay is what recovers a delivery that was lost. Scopes: read:patients; appointment and bill changes also need read:appointments / read:bills.

Request

Unknown parameters are a 400.

Response

Cursors are strictly increasing per organization but not consecutive. A change tells you what changed; read the resource for its state (for a group, POST /v4/patients/history). patientId is the source chart the change belongs to, when that chart is mirrored.

Change types

Ordering and delivery guarantees

  • Committed only. Changes are written by the database in the same transaction as the data change; a rolled-back write leaves no change.
  • Commit order. A change receives its cursor after it commits, from a single sequencer, so once you have read cursor N no change with a smaller cursor can appear later. A sequence number taken before commit is never exposed. Changes sequenced in the same pass may be numbered in any order among themselves.
  • Always store nextCursor, even from an empty page: when hasMore is false it is the feed head, so a quiet organization’s cursor keeps moving and never ages past retention.
  • Latency. Sequencing runs every minute; the appointment sync runs every five.
  • At least once. The same resource can appear several times; process idempotently by resourceId and re-read.
  • Retention: 30 days. A cursor older than that answers 409 with cursor_expired: re-read current state (e.g. the history endpoint) and resume from the cursor in the message. Omitting after starts at the oldest retained change.

Webhook

changes.available (scope read:patients) is sent after each sequencing pass that produced changes for your organization:
It is best effort. Poll GET /v4/changes on a slower cadence as well.