Webhook Trigger
Exposes a unique URL (https://<...>.supabase.co/functions/v1/webhook-receiver/wh_...) that external systems — Stripe, GitHub, HubSpot, anything — can POST JSON to. Every POST that validates triggers one execution of your workflow.
When to use
- A third-party service supports webhooks and you want their events to drive a workflow.
- You need to accept inbound data from a custom integration you don't have a connector for yet.
- Any "when X happens in their system, do Y in ours" use case.
Configuration
| Field | Required | What it does |
|---|---|---|
expectedPayload | No | Example JSON. Used only by the data picker so downstream nodes have something to drill into. It is not validated against incoming requests. |
verificationSecret | No | Shared secret for HMAC signature verification. When set, incoming requests must include a matching X-OneHazel-Signature header or the request is rejected with 401. |
The webhookId (the wh_... part of the URL) is managed internally by OneHazel and displayed in the node configuration drawer. It is stable — you can paste it into the third-party system's webhook settings and it won't change unless you delete the node.
Signature verification
When verificationSecret is set, the receiver computes HMAC-SHA256(secret, raw_body) hex-lowercased, and compares against the X-OneHazel-Signature header. Requests without a matching signature get a 401 and the workflow does not fire.
If the third-party system supports HMAC-SHA256 signatures with the same scheme (Stripe and GitHub both do a variation), set the secret and they'll be verified automatically. If not, leave it blank — the URL is still unguessable enough that unauthenticated POSTs are rare.
Deduplication
Every incoming request is deduplicated by X-Request-Id header for 24 hours. If a sender retries without bumping the ID, the receiver returns 200 but does NOT re-fire the workflow. If the sender doesn't set the header, a hash of the body is used.
What it outputs
The entire parsed JSON body is exposed to downstream nodes as {{trigger.data.*}}. Request headers are available at {{trigger.headers.*}}.
Gotchas
- Body must be valid JSON. Non-JSON bodies are rejected with 400.
- POST only — GET/PUT/DELETE are rejected.
- Webhook URL is per-node — if you delete and recreate the node you get a new URL and have to update the third-party system.