Notion’s webhooks are signal-only: the payload tells you that something changed — a page id, a list of property ids — never the new values. Every event forces a follow-up GET, and those follow-ups burn the same 3 requests/second budget your automation is already rationing. Here is the failure mode in detail, and what a payload should carry instead.
A typical delivery for a property change looks like this (July 2026, per Notion’s webhook reference):
{
"type": "page.properties_updated",
"entity": { "type": "page", "id": "<page_uuid>" },
"data": {
"parent": { "type": "data_source_id", "data_source_id": "..." },
"updated_properties": ["<prop_id_1>", "<prop_id_2>"]
}
}updated_properties is a list of property ids. No old value, no new value, no card title, no column name. To learn what happened you call the API again. A few more contract details that matter when you build on it:
Now put those properties together on a busy board. A batch step moves 50 cards. You receive ~50 webhooks that each say “something changed on page X.” Your handler dutifully issues 50 follow-up reads — plus block fetches for the cards with content — straight into a 3 req/s limiter. The queue backs up, some reads 429, your retries collide with the next batch’s events, and if a delivery drops mid-storm there is no replay to recover it.
The perverse part: the busier your board, the more your notifications consume your API budget. Teams end up standing up a caching proxy just to answer “what changed?” — infrastructure whose only job is to work around the payload shape.
Novum OS events carry the change inline. The same card move looks like this (the envelope is a locked contract, FUNCTIONAL_SPEC §10.5):
{
"object": "event",
"event_id": "1d4f3c2a-7a06-4b3a-b3f0-2e9a47b5d1c3",
"event_type": "card.moved",
"delivered_at": "2026-05-12T16:00:01.123456Z",
"entity": { "type": "page", "id": "0192a4b2-..." },
"data": {
"card_id": "0192a4b2-...",
"board_id": "0192a4b2-...",
"column_id": "0192a4b2-...",
"from_column_id": "0192a4b2-...",
"to_column_id": "0192a4b2-..."
}
}data: a move carries from/to columns; an update carries a diff map of the fields that changed. Most consumers never make a follow-up call.event_id and a retry can never double-apply. Failed deliveries retry on a backoff schedule, land in a dead-letter queue, and can be replayed with the same event_id.The pattern that suffers least on sparse payloads: subscribe to the narrowest event types available, dedupe aggregated deliveries before fetching, keep a local last-known-state cache so unchanged fields don’t trigger reads, and give webhook handlers their own slice of the rate budget so a notification storm can’t starve your writes.
Point your webhook receiver at a board that sends the diff — free tier, no card, webhooks included.
Create accountNotion is a trademark of Notion Labs, Inc. Novum OS is an independent product and is not affiliated with or endorsed by Notion Labs. Third-party behavior reflects public documentation as of July 2026 and may change.