Notion is celebrated for its flexibility and user-friendly interface, but its lack of native webhook support has left some developers seeking alternative integration methods. In this article, we'll explore a creative approach to achieve real-time updates by tracking page statuses and triggering webhooks only when changes occur.
Tracking Notion Changes with Webhooks
A normal architecture would be to poll all API for changes in databases, pages and blocks to check for updates. While this method is not truly real-time like webhooks, it can be an effective workaround to keep your application up-to-date with the latest changes in Notion. The biggest drawback is that you are polling too many data, and if your databases get big enough you will hit Notion's rate limits very soon.
So my strategy is to track only the status and archived property of the pages and trigger a webhook when these values change. The process would look like this:
1. Fetch All Pages:
Periodically query the Notion API to retrieve all pages that you want to track.
2. Store the Current Status and Archived Property:
For each page, store the current status and archive property that you want to track in your webhook server's persistant database or memory.
3. Polling Loop:
Set up a polling loop that repeatedly fetches the pages' data from Notion at a defined interval. You can decide on an appropriate polling frequency based on your requirements and Notion's rate limits.
4. Compare Status Changes:
During each poll, compare the fetched pages' status and archive property with the stored values in your webhook server. Detect any changes for individual pages, I would classify the output of this process into 4 types, and your webhook may create different events based on these types
- A new page is created. Note that at the first database sync, your notion server may compare and see that there is a new page, but in fact it is an existing one yet not yet been saved to database. The treatment, would be to disable this type of webhook on the first run, and enable it again subsequently. Alternatively, you may compare the created date of a page with the current time, and only fire this webhook event if it is created within a certain time, say 10 minutes.
- A page status is changed
- A page is archived. Note that Notion do not delete your page, so a delete action performed by user will update archive status to TRUE.
- A page is unarchived. This happened when a 'deleted' page is recovered from user trash bin.
5. Trigger Webhook:
If a page's status or archived has changed, trigger the webhook with the relevant information. The webhook can perform any desired actions based on the status change, such as sending notifications or performing further processing.
It can be illustrated with this diagram:
Optimization
The key here is avoid rate limits, and reduce unneccessary data stored in your database. To optimize storage and retrival of my database, only 3 fields are stored:
- ID of the page
- Status of the page
- Archived property of the page
Nothing else really, even the ID of Notion databases and all the blocks belong to the page. The idea is to keep this webhook server simple, and the webhook consumer will be the one who make another query to Notion database on the updated pages.
Navigating the rate limits of Notion is the other crucial thing to consider, a very simple solution is to get your loop interval right. More sophisticated (and optimized for data freshness) strategies are available, but let's keep it out of scope of this article.
I am using this architecture at our telemedicine website Wellcare to manage various contents and databases including articles and doctor profiles - and it works just fine. Webhook is the part that cannot be missed in any microservice system. I do hope that Notion will implement the native webhook soon, so this article will become absolute!

Latest comments (0)