
How webhooks work: A simple example
Let’s walk through an example from start to finish:Your server receives the event, verifies it, and calls the Notion API to fetch the updated title using the page ID from the event.
Getting started with webhooks
Step 1 - Creating a webhook subscription
To receive webhook events, you’ll need to create a subscription through your integration settings. You’ll need to:Visit your integration settings.
Enter your public Webhook URL — this is the public endpoint where you want Notion to send events. It must be a secure (SSL) and publicly available endpoint. Endpoints in localhost are not reachable.

Step 2 - Verifying the subscription
When you create a subscription, Notion sends a one-time POST request to your webhook URL. The body of the request contains averification_token, which proves that Notion can successfully reach your endpoint.
Example payload with verification_token:
Inspect the incoming request at your endpoint and extract the
verification_token from the JSON payload.- (Optional): Securely store this token for payload validation setup later, in step 3.
Go back to the Webhooks tab within your Notion integration UI and click ⚠️ Verify on the bottom left of the page

Changing your webhook URL or event subscriptionsYou can only change the webhook URL before verification. After verification, if you need to change the URL, you must delete and recreate the subscription. You can change the subscribed events at any time.
Step 3 - Validating event payloads (Recommended)
To help ensure the security of your integration, Notion includes a cryptographic signature with every webhook event we send. This allows you to verify that the payload was sent by Notion and hasn’t been modified in transit. While payload validation is optional, we recommend implementing it for any production environment.Using a no-code or low-code platform?If you’re using a no-code or low-code platform (like Zapier, Make, or Pipedream), you may not have access to custom code for signature verification — and that’s okay. Validation is encouraged, but not required for webhooks to work.
How it works
In the previous step, Notion sent a one-timeverification_token to your webhook URL. You’ll use this token to verify the authenticity of all subsequent webhook events.
Every webhook request from Notion includes an X-Notion-Signature header, which contains an HMAC-SHA256 hash of the request body, signed with your verification_token.
Sample X-Notion-Signature from Notion:
verification_token along with the event’s payload to recompute the signature and verify the request’s authenticity. If they match, the payload is trustworthy.
Sample code for computing the signature and validating the webhook payload:
verification_token.
Testing your webhook subscription
Once your webhook subscription is set up and verified, it’s a good idea to test that everything is working as expected. Below are three common test scenarios you can try, each corresponding to a supported event type. These tests simulate typical content updates and help ensure your endpoint is receiving and processing events correctly.Test 1 - Change a page title
This test checks your webhook’s ability to handle aggregated events, which are delivered with a short delay to avoid sending redundant updates. You’ll need to:Wait a minute or two because aggregated events like
page.content_updated are batched and may not be sent immediately.Test 2 - Add a comment
This test checks event delivery for comments, which require specific capabilities. You’ll need to:
Important:
To receive this event, your integration must include the
comment read capability in its configuration. You can confirm this in the Capabilities tab of your integration’s settings.
Test 3 - Modify a database schema
This test verifies that structural changes to databases are triggering events. You’ll need to:Make a schema change — for example, add a new property (column), rename an existing one, or delete a property.
Troubleshooting tips
If your webhook isn’t receiving events as expected, here are a few things to double-check. These are the most common reasons developers miss events during setup or testing.🔒 1. Check access permissions
Make sure the integration has access to the object that triggered the event. For example, if a new page is created inside a private page your integration doesn’t have access to, the event won’t be triggered.✅ 2. Confirm capabilities
Some event types require specific capabilities to be enabled for your integration. For instance, to receivecomment.created events, your integration must have the “comment read” capability selected. Without it, even if your integration has access to the page, the comment event won’t be delivered.
You can view and update your integration’s capabilities in the Capabilities section of your integration settings.

