updated_after parameter on the /articles, /stories, and /calendar_events endpoints to fetch only records that changed since your last sync.
An updated_after request is a resumable walk, not a snapshot. Results are ordered by updated_at ascending and cursor-paginated, so you must follow the cursor to the end before you record a new watermark.
How to poll for updates
1
Request records changed since your watermark
Pass Results come back ordered by
updated_after with your stored watermark, and request updated_at so you can track your position from the data itself:updated_at ascending, cursor-paginated.2
Drain the cursor
Follow
pagination.next_cursor, resending the same updated_after value alongside it, until next_cursor is null.3
Track the highest updated_at you saw
As you process records, keep the maximum
updated_at across every record drained in this walk. That value, not your clock, is your new high-water mark.4
Commit the watermark with a one-minute overlap
Once the walk finishes, store the highest
updated_at you saw minus a one-minute overlap as your new watermark. Reconcile the re-delivered records by id on the next poll.Polling example
Re-delivery at the overlap margin is expected. Reconcile byid so repeated records update in place rather than duplicating.
updated_after accepts YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ (optionally with milliseconds). Python’s datetime.isoformat() emits microseconds and a +00:00 offset, both of which are rejected with a 400. Use strftime("%Y-%m-%dT%H:%M:%SZ") as shown above.How the updated_after parameter works
Whenupdated_after is set:
- Results are ordered by
updated_atascending, withidas a tiebreaker, so a partially drained walk can be resumed from its cursor - Results are cursor-paginated and capped at
limit. Followpagination.next_cursoruntil it isnull - The filter is strict (
updated_at > your watermark), so a record is not redelivered unless it changed again. This is why the one-minute overlap matters: it is what makes redelivery happen at the margin - The walk covers the full served dataset. A first sync from an old watermark returns history, not just recent records
- ETag caching is disabled since the results are time-sensitive
- The response includes both newly created and recently modified records
updated_at. Request it explicitly when using field projection.
Removals are not signalled
A record that is withdrawn, hidden, or otherwise falls out of visibility simply stops appearing in walks. There is no tombstone and no deletion event. A mirror built this way is append-and-update, not an exact replica of the served dataset.Calendar events
Calendar events sync the same way, at/api/v1/calendar_events, with two behaviors specific to the endpoint.
Sync walks include past events. The endpoint’s default listing returns upcoming events only, floored at today by the issuer’s local date. Passing updated_after lifts that floor, so a sync walk covers the full served dataset. This matters because the most common calendar change lands on a past event: every event flips from scheduled to published roughly two days after its date. Corrections and reschedules to past events reach mirrors the same way.
Lifting the floor is forward-looking. Updates to past events that occurred before your currently stored watermark are not replayed. To backfill that history, reset your watermark to an old timestamp and run a fresh sync, which returns full history exactly as it does for articles and stories.
scheduled and published events and exclude cancelled by default, so a scheduled → cancelled transition never surfaces in a default sync walk. To track cancellations, poll separately with status=cancelled, or use cancellation alerts.