Send a Webhook to Notion: Transform & Forward Any Payload

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 & Forward Any Payload

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 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

  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

  1. Go to 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

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

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

Configure your source service's webhook to point at your Webhook Relay public URL. Trigger an event — or replay one from the 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

Get started

Create a free Webhook Relay account and turn any webhook into Notion rows — no servers to run. New to webhooks? Start with what is a webhook and how to transform webhooks.