GET /v1/changes returns immutable events created in the same transaction as a Nektir publication. It can be used as a statewide newest-first feed or filtered to one product with product_id or sku.
What an event means
Every event describes a difference between two published Nektir observations. Itstimes.retrieved_at is when Nektir retrieved the public response, while times.published_at is when the validated observation became API-visible. times.source_updated_at remains null unless Utah DABS supplies an update time.
Inventory decreases are not inferred sales or purchases. Likewise, store_inventory_first_observed establishes a baseline and must not be labeled a restock. A catalog-presence transition does not establish zero inventory.
The semantics field is a machine-readable guardrail:
reported_observation_change_not_inferred_saleapplies to changed aggregate or store inventory.baseline_observation_not_restockapplies to the first retained store observation.source_presence_change_missing_does_not_imply_zero_inventoryapplies to catalog-presence transitions.published_value_changeandpublished_presentation_changedescribe differences in the Nektir projection.
Event types
Use the comma-separated
types filter when an application needs only selected event classes.
Stable pagination
Every response is capped at the publication revision inX-Publication-Revision. The first page also freezes the largest eligible event ID within that revision. Follow links.next or return meta.page.next_cursor unchanged. Events published concurrently or afterward are excluded from that pagination walk and appear when the application starts a new walk without the old cursor.
History begins at meta.history.tracking_started_at; Nektir does not fabricate a backfill for time before tracking began. earliest_available_at, latest_available_at, and retained_event_count describe events matching the request filters and the first page’s frozen upper bound. retention_days states the current storage policy. Expired cursors return 410, just like other collection endpoints.
The current pilot retains change events for 400 days (about 13 months). The value is returned by the API rather than assumed by clients and can be increased after measured event volume and storage cost are known. Any shorter value shown in generated examples is not the runtime policy.
Building a poller
- Poll without a cursor and record event
idvalues your application has processed. - Follow every
links.nextvalue to finish the frozen page set. - Deduplicate by event
id; delivery is read-based and should be treated as at least once by consumers. - On the next poll, request a new first page. Use
sinceas a retrieval-time optimization, not as the deduplication key.