---
title: "Send a Webhook to Notion | WebhookRelay"
meta:
  "og:description": "Send any webhook to Notion. Step-by-step guide to forward incoming webhooks into a Notion database, transforming the payload into the Notion API format in flight."
  "og:title": "Send a Webhook to Notion"
  description: "Send any webhook to Notion. Step-by-step guide to forward incoming webhooks into a Notion database, transforming the payload into the Notion API format in flight."
---

![Stripes](https://webhookrelay.com/blog/webhook-to-notion/images/stripes.svg)

# **Send a Webhook to Notion**

Send any webhook to Notion. Step-by-step guide to forward incoming webhooks into a Notion database, transforming the payload into the Notion API format in flight.

![Send a Webhook to Notion: Transform &amp; Forward Any Payload](https://webhookrelay.com/blog/webhook-to-notion/images/blog/heroes/route.jpg)

You have a service that fires webhooks — a signup form, a payment provider, a CRM, a monitoring tool — and you want each event to land as a row in a **Notion database**. The problem: the Notion API won't accept the raw webhook. It expects a bearer token, a `Notion-Version` header and a `properties` object that matches your database schema exactly, and the payload your source sends never looks like that.

[Webhook Relay](https://webhookrelay.com) sits in the middle. It receives the incoming webhook at a stable public URL, **transforms** the payload into the Notion "create a page" format, and delivers it to the Notion API — no glue server, no Lambda, no maintenance.

## [How it works](#how-it-works)

1. Your source service POSTs its webhook to a Webhook Relay endpoint.
2. A transformation function parses the payload and builds a Notion API request body.
3. Webhook Relay forwards that to `https://api.notion.com/v1/pages` with your integration token, and a new row appears in your database.

## [Step 1: Create a Notion integration and share your database](#step-1-create-a-notion-integration-and-share-your-database)

1. Go to [notion.so/my-integrations](https://www.notion.so/my-integrations) and create a new **internal integration**. Copy its secret (it starts with `secret_` or `ntn_`).
2. Open the database you want to write to, click the **•••** menu → **Connections** → add your integration so it has access.
3. Note the **database ID** — it's the 32-character string in the database URL.

## [Step 2: Create a Webhook Relay output to the Notion API](#step-2-create-a-webhook-relay-output-to-the-notion-api)

Create a bucket with a public input, then add an output pointing at the Notion API:

- **Output destination:** `https://api.notion.com/v1/pages`
- **Headers:**
  - `Authorization: Bearer <your-integration-secret>`
  - `Notion-Version: 2022-06-28`
  - `Content-Type: application/json`

## [Step 3: Add a transformation function](#step-3-add-a-transformation-function)

Attach a function to the output that reshapes the incoming webhook into a Notion page. Map the fields you care about to your database's property names:

```
-- incoming payload is in r.RequestBody
local body = json.decode(r.RequestBody)

local page = {
  parent = { database_id = "YOUR_DATABASE_ID" },
  properties = {
    Name = {
      title = { { text = { content = body.name or "New event" } } }
    },
    Email = {
      rich_text = { { text = { content = body.email or "" } } }
    },
    Amount = { number = body.amount or 0 }
  }
}

r:SetRequestBody(json.encode(page))
```

Make sure each key under `properties` matches a column in your Notion database and uses the correct type (`title`, `rich_text`, `number`, `select`, `date`, `checkbox`).

## [Step 4: Point your source at the URL and test](#step-4-point-your-source-at-the-url-and-test)

Configure your source service's webhook to point at your Webhook Relay public URL. Trigger an event — or replay one from the [Webhook Bin](https://webhookrelay.com/blog/webhook-to-notion/webhook-bin/) — and a new row appears in Notion within seconds. If the API rejects the request, the Webhook Relay logs show Notion's exact error so you can fix the property mapping.

## [Going further](#going-further)

- **Fan out:** send the same event to [Slack](https://webhookrelay.com/blog/webhook-to-notion/blog/webhook-to-slack/), [Discord](https://webhookrelay.com/blog/webhook-to-notion/blog/webhook-to-discord/) or a [Google Sheet](https://webhookrelay.com/blog/webhook-to-notion/blog/webhook-to-google-sheets/) at the same time with [multiple destinations](https://webhookrelay.com/blog/webhook-to-notion/features/webhook-multiple-destinations/).
- **Test locally first:** [receive the webhook on localhost](https://webhookrelay.com/blog/webhook-to-notion/blog/what-is-webhook/) to inspect the real payload before you write the mapping.
- **Secure it:** [verify the source signature](https://webhookrelay.com/blog/webhook-to-notion/blog/verify-webhook-signature/) before forwarding so only legitimate events reach Notion.

## [Get started](#get-started)

[Create a free Webhook Relay account](https://my.webhookrelay.com/register) and turn any webhook into Notion rows — no servers to run. New to webhooks? Start with [what is a webhook](https://webhookrelay.com/blog/webhook-to-notion/blog/what-is-webhook/) and [how to transform webhooks](https://webhookrelay.com/blog/webhook-to-notion/features/transform-webhooks/).