Skip to main content
Sync endpoints let you maintain a local copy of Grade data. Start with a paginated copy, then poll with the saved cursor to receive changed records and removal IDs. An unchanged feed returns an empty page. You choose when to poll. Every request requires X-Application-Id and X-Api-Key. Keep a separate local collection and cursor for each agency, endpoint, campaign, and supported filter set. Existing list endpoints keep their behavior. Each new feed has an explicit record format documented on its page; it is not a drop-in replacement for list responses containing previews, aggregates, or display conversions.

Apply a page and save its cursor together

  1. Start without cursor, using an empty local collection for this sync scope.
  2. Replace or insert each data record using its identity from the table above.
  3. Delete each removedIds entry. Unknown IDs are harmless.
  4. Commit nextCursor in the same local transaction as those changes.
  5. When hasMore is true, immediately request another page with that cursor.
  6. When hasMore is false, keep the cursor for your next poll.
Save the cursor from empty pages too. Continue through pages containing only removals. Use one worker at a time for each local copy; applying an older response after a newer one could overwrite newer state.
Cursors do not expire by age. Pausing an integration, restarting it, changing the page size, or rotating its API key does not require a full reload. A cursor stays bound to its feed and agency/campaign scope, and every request still checks access.

Shared request and response

The six new feeds accept only cursor and limit. Campaign media additionally supports its documented initial filters. Unknown parameters are rejected so a misspelled filter cannot silently broaden a sync. Pages target 1 MiB of record data. A single larger record is returned intact; page length can be smaller than limit.
data contains complete replacements, not partial patches. removedIds means the record no longer belongs in this local view: for example, it was deleted, moved to another scope, or became unavailable. Restored records return as upserts. Campaign media also removes records that leave its saved filters.

Concurrent changes and retries

Each page reads a consistent current state. A multi-page run is not a frozen export: edits during paging appear in a later page or the next poll. Transactions that started before the checkpoint and committed later are included too. Delivery is at least once. Repeated records and removals are safe when applied idempotently. Multiple edits can become one replacement containing the latest state; these feeds are not audit logs of intermediate edits. On an API error or failed local transaction, retry the last committed cursor. Keep your local data. Do not automatically restart the sync on an error.
  • 400: fix malformed parameters or a damaged/wrong-scope cursor. There is no routine cursor-expiry error.
  • 401 / 403: restore valid credentials or the required scope, then resume.
  • 404: the requested campaign is unavailable to your agency. Do not reuse its cursor for a different campaign.
  • 429 / 5xx: back off and retry the same saved cursor; honor Retry-After when supplied.

Client example

The repository demo exports sync from sdk-demo/backend/src/sdkClient.js. Supply your own database adapter and transaction implementation:
Use sync.contracts, sync.eligibility, sync.payouts, sync.transactions, or sync.trackedMedia for the other new feeds. Agency feeds omit campaignId. The deployed campaign media feed retains its existing mediaSync client and campaignCreatorMediaId identity; see its client example.

What syncing improves

Later polls transfer and hydrate only records affected by changes. The initial copy still reads the full scope, in bounded pages. If every record changes, catching up still requires every record. Page size bounds individual requests; it does not guarantee less total work when downloading everything. For date-range charts, campaign totals, and payable previews, use the existing analytics and payment endpoints. Sync records provide durable facts for a local copy; they do not continually recompute financial or analytical aggregates.