updated_after parameter on the /articles, /stories, /events, 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. Events are the exception: a merged or removed event comes back in the walk as a tombstone. See Events below.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.
Events
Events sync the same way, at/api/v1/events, with one addition: the walk tells you when an event you hold is merged or removed.
Merged and removed events arrive as tombstones. Two events can turn out to describe the same development and merge, or an event can be removed. A tombstone carries only id, status, merged_into (the surviving event’s id, when merged) and updated_at. When one arrives, drop the event from your mirror, and if merged_into is set, fetch the surviving event. Tombstones appear only in updated_after walks, never in the default listing.
Some filters do not apply to tombstones. country, category, sources, source_type, and content_type filter by an event’s articles. A tombstone has none left, so a walk using them misses tombstones. listed checks each company’s current listings, so it can also drop a tombstone. Poll without these filters if you need every merge and removal.
sort and window cannot be combined with updated_after. Sending either one with it returns a 400.
company_ids and story_ids can change without moving an event’s updated_at, for example when a story is withdrawn. Treat them as current as of your last poll.