Request
Missing, invalid or future
updatedSince returns 400 invalid_field.
Response
Because a paused or closed Matter arrives with its reason attached, a nightly run reconciles stopped files straight from the list page instead of issuing a second request per Matter.
Party identity, addresses and contacts are deliberately kept out of list pages — a nightly catch-up should not move personal data it does not need. Use
etag to find the Matters that actually changed, then GET only those for the full representation.The run boundary
You never have to reason about clocks. CasePath IQ tells you how far each run covered, and you hand that value straight back next time.syncedThrough appears only on the final page of a run — the page where nextPageToken is null — and is null on every earlier page. That is deliberate: if a run fails half way through, there is no boundary for you to save, so the next run safely re-reads the same window instead of skipping it.
It is returned even when matters is empty, so a quiet night still moves you forward.
The value is held a little behind real time. A Matter’s
updatedAt is set inside the write transaction but only becomes visible when that transaction commits, so a boundary set at “now” could skip a Matter that was mid-commit — permanently, because nothing would ever bump its updatedAt again. Holding the boundary back keeps it clear of that window.This is why you should not add an overlap, a skew allowance, or a safety margin of your own. Send syncedThrough back exactly as given. The lag is ours to maintain, and its size may change.Recommended sync loop
1
Choose the lower bound
Use the
syncedThrough you stored after your last completed run, or the initial UTC boundary agreed during onboarding. Nothing else — not your own clock, not the response time, not the greatest updatedAt you saw.2
Read the first page
Send
clientCode, updatedSince, and an optional limit. Omit pageToken.3
Apply current state
Reconcile each item by
matterId. Because this is current state rather than an event stream, repeated items are safe to apply again.A sync item is a summary projection, not the Matter. It carries no parties, debt or instruction, so writing it over a stored full Matter would erase those fields. Either keep sync items in their own synchronization projection, or merge each one into what you hold without removing the fields it does not carry.Compare each item’s etag with the tag you stored for that Matter. Unchanged means nothing you hold is stale, so skip the detail read. Changed means GET the Matter, and store that full representation together with the etag the GET returned — it is also the If-Match value for your next write.4
Follow every page
While
nextPageToken is not null, send it unchanged and keep the original Client, lower bound, and limit. A token is bound to the integration, Client, filter, and snapshot watermark.5
Advance after the final page
Once every page has been applied successfully, save the final page’s
syncedThrough as your new boundary. If the run failed or was abandoned, save nothing and repeat the same updatedSince next time — re-reading is always safe, because each item is current state rather than an event.Store the boundary and the applied rows together, so a crash can never leave you with an advanced boundary and unapplied data.updatedAt ascending and then matterId ascending, so a batch of Matters sharing one timestamp pages cleanly and never straddles a page edge unpredictably. Do not parse, modify, or reuse a page token with another Client or filter, and keep one boundary per Client — a syncedThrough from one Client’s run means nothing for another.
Because updatedSince is inclusive, a Matter sitting exactly on the boundary may arrive twice across consecutive runs. Upserting it again is a no-op, and its etag will be unchanged, so there is nothing to reconcile.
What changes updatedAt
updatedAt advances when partner-visible state changes through:
- A materially different Matter PUT or PATCH
- A first accepted Payment observation
- An accepted lifecycle operation
- A CasePath IQ workflow or intake transition
updatedAt.
When to use GET one
Use the list endpoint for catch-up and reconciliation. Use GET one by client reference ID ormatterId when you need the full partner-facing Source representation, including parties, debt, instruction, and server-owned state identifiers — normally only for the Matters whose etag changed.
Do not treat the list as a complete audit history. Multiple changes between sync runs may appear as one latest current-state item.