For the complete documentation index, see llms.txt. This page is also available as Markdown.

🔗Webhook Technical Reference

Canonical maker page for inbound and outbound HTTP. Not sure which product? Start with Workflow vs Messaging Webhooks. Admin kill switches, host env files, and internal endpoints stay in repo docs/ — not here.

What this is / when to use it

Direction
Meaning
NotionApps surface

Inbound

An external tool POSTs JSON into NotionApps and starts work

Workflow trigger webhook_received, or Messaging inbound that publishes a message

Outbound

NotionApps POSTs JSON to a URL you own

Notify (fire-and-forget), Call webhook and wait (sync JSON), or a Messaging subscriber of type Webhook

Use webhooks when another system is the first place work begins (CRM, payments, a form tool), when a downstream system must hear the result, or when a button must wait for Make and then refresh the already-open tab.

When not to: you only need email. Use send_notification. You are still exploring — start with the wizard, not HTTP.

Before you start

  1. Workflow entitlement is on (Messaging External API level if you use Messaging webhooks).

  2. You have the application id from the builder URL.

  3. You can generate a webhook secret in the workflow builder when the trigger is Webhook received. Copy it once — it is not shown again.

  4. You have an outbound catcher (webhook.site, Hookdeck, Zapier Catch Hook) if you will test outbound.

  5. The workflow is published / active. Drafts can accept HTTP and create zero runs.

Create a webhook secret

The secret belongs to this app. Workflow inbound and Messaging inbound both use it.

  1. Open Automation → Workflows.

  2. Select (or create) a workflow whose trigger is Webhook received.

  3. Open External webhook intake.

  4. Enter a name you will recognize later, for example Make production.

  5. Choose an active term: 30, 90, 180, or 365 days, or No expiry.

  6. Click Generate secret.

  7. Copy the value immediately. Paste it into Make, Zapier, or your sender as:

The builder also accepts Authorization: Bearer {SECRET} and x-workflow-webhook-token: {SECRET}.

The list then shows only a prefix (for example na_wh_8f3a2c1b), the name, status, days left, and last used. The full secret is never shown again.

Rotate

  1. Generate a new secret (you can have up to five active secrets).

  2. Update Make, Zapier, or the sender to the new value.

  3. Confirm a test POST succeeds.

  4. Revoke the old secret.

You cannot revive a revoked secret. Generate a new one instead.

Rules

  • A secret for App A cannot post into App B.

  • Revoked or expired secrets return 401.

  • If inbound webhooks are disabled for the app, generate is blocked.

  • Do not put the secret in a Notion property that guests can open.

Build it

Webhook intake template (recommended first route)

Automation → Workflows → Start from a template → Webhook intake, or recreate:

Order
Step
Purpose

1

Condition

e.g. payload.status equals approved

2

Create record

Map payload.name, payload.email

3

Notify (channel = Webhook)

Outbound proof to your catcher

4

End

Done

Trigger: webhook_received on the application.

Replace example field names with your Notion properties. Full step list: Step catalog.

Inbound URL shapes

{API_HOST} is the API for your environment (production https://api.notionapps.com unless support tells you otherwise). Prefer the app alias URL from the builder so the event is already scoped.

Auth (maker)

Use the secret you generated above. Do not guess a platform token and do not reuse a secret from another app.

If a request returns 401/403, the secret is wrong, revoked, expired, or bound to a different app. If it returns 503 about a token not configured, that is an environment problem — contact support.

Test inbound

  1. Publish the workflow.

  2. POST JSON with a unique event_id / idempotency_key every try (retries can look like “nothing happened”).

  3. Example body:

  1. Expect an accepted response and runs_created >= 1 when the trigger matched.

  2. Confirm the Notion row and, if you added Notify, the catcher POST.

Test outbound

  1. Notify step → Channel Webhook → paste the catcher URL.

  2. Subject/body you will recognize.

  3. Fire inbound (or Simulate if Simulate sends outbound in your build).

  4. Confirm the catcher shows headers + body.

Call webhook and wait (open-tab refresh)

Use Call webhook and wait when a button must POST Make (or another webhook), receive JSON, then Refresh or Open screen on the same open tab. This is not fire-and-forget Notify webhook.

  1. Add the step and paste the Make webhook URL.

  2. Leave the sync timeout at 8000 ms unless you need a shorter wait (max 12 seconds on the tap).

  3. In Make, end with Webhook response and return JSON, for example { "ok": true, "cart_record_id": "…" }.

  4. Map a later Open screen record id to context.<this_step_id>.cart_record_id when Make returns one.

  5. Follow with Refresh / Open screen / Show message.

What the user sees:

  • Make answers within 8 seconds: the following UI steps run on the open tab.

  • Make is still going: Working… then the app polls the run for 45 seconds.

  • Still pending: “This is taking longer. Refresh to see the cart.”

  • 4xx / 5xx in the sync window: error, no refresh, no retry.

Live screen updates must be on for the app, or Refresh after this step will not update the open tab. The switch is off by default. NotionApps turns it on from Workflow Operations → Controls.

Inbound webhooks Make fires back at NotionApps still cannot refresh an already-open tab.

Every control

Control
Where
What it does

Trigger Webhook received

Workflow

Starts a run from HTTP.

Intake URL (central / app alias)

Builder

Where senders POST.

Generate secret

External webhook intake

Creates a per-app secret. Plaintext is shown once.

Name + active term

External webhook intake

Label and 30 / 90 / 180 / 365 days or no expiry.

Revoke

External webhook intake

Immediately rejects that secret.

Token header

Sender (Make / Zapier)

x-notionapps-webhook-token.

Condition on payload.*

Step

Gate.

Create/update record maps

Step

payload.field → Notion.

Notify channel Webhook

Step

Fire-and-forget outbound.

Call webhook and wait

Step

Sync POST; waits for JSON Webhook response.

Messaging inbound / subscriber

Messaging

Separate product; needs External API level. Uses the same app secret.

Idempotency key

Payload

Dedupes retries.

What users see

Inbound and fire-and-forget Notify usually show nothing to the current tab. Call webhook and wait can Refresh / Open screen / Show message on the open tab when Live screen updates is on. Operators may also see a Work Queue item or Notification if you added those steps. An inbound sender sees only the HTTP status.

Limits and plans

  • Messaging webhooks need External API. Workflow Notify webhooks and Call webhook and wait need Workflow on, not Messaging levels.

  • Up to five active secrets per app. Revoke or expire one before generating another if you are at the cap.

  • After the first active secret, the shared platform token no longer works for that app.

  • Call webhook and wait needs a reachable HTTPS URL. Make must return JSON via Webhook response.

  • Unpublished workflows: HTTP may return accepted with runs_created: 0.

  • Payload size and rate limits follow the API. Keep test bodies small.

  • Do not put secrets in Notion properties that guests can open.

Example

You generate a secret named Make production with a 90-day term. Make stores x-notionapps-webhook-token and POSTs { status, name, email } to the app alias URL. Condition requires approved. Create record on Leads. Notify the outbound catcher. The sample lead appears in the app list; the catcher logs the outbound POST.

Fix problems

Symptom
Likely cause
What to do

401

Wrong, revoked, or expired secret, or a secret from another app

Generate a new secret if you lost the value. Confirm the prefix matches this app. Stay on one environment.

401 after you generated a secret

Sender still uses the old shared platform token

Update Make/Zapier to the new secret.

Generate is blocked

Inbound webhooks are disabled for the app

Ask NotionApps to turn inbound back on.

At the 5-secret cap

Too many active secrets

Revoke or expire one, then generate.

Accepted, 0 runs

Draft, or trigger not webhook_received

Publish. Check trigger.

Condition failed

payload.status mismatch

Log the raw body. Fix the path.

Outbound missing

Notify not Webhook, or URL wrong

Catcher URL. Publish.

Open tab stale after Make

Used Notify, or Make has no Webhook response, or live screen updates is off

Use Call webhook and wait. End Make with Webhook response JSON. Ask NotionApps to turn the switch on.

Messaging 403

Level below External API

Request access.

Workflow vs Messaging Webhooks. 31 Aug 2026 Release. Trigger catalog. Which automation.