Events are derived from consecutive observations, never written independently — so the log is reproducible from the store rather than asserted. Six types, one uniform shape, replayable by cursor.
| Field | Type | Notes |
|---|---|---|
| event_id ·always | string | Also the webhook-id and your idempotency key. |
| seq ·always | int | Monotonic. Use as the replay cursor. |
| type ·always | enum | price.changed | price.threshold_crossed | availability.changed | seller.changed | policy.violated | match.degraded. |
| occurred_at ·always | timestamp | The observation time that produced it. |
| previous / current | object | Both sides of the change, always. |
| source | object | Provenance of the observation behind it. |
{
"event_id": "evt_01JQ8Z3M4K", "seq": 88421,
"type": "price.changed",
"occurred_at": "2026-09-07T14:21:59Z",
"product_id": "prd_8Fk2xQ", "listing_id": "lst_2c81", "seller": "bestbuy",
"previous": { "price_minor": 31999, "observed_at": "2026-08-21T02:10:44Z" },
"current": { "price_minor": 19800, "observed_at": "2026-09-07T14:21:59Z" },
"source": { "channel": "direct_api", "confidence": 1.00 }
}It is the only warning that a comparison has quietly started comparing two different products. Most integrations ignore it and then wonder why a competitor appeared to slash prices overnight.