Webhook
Trigger workflow execution when an external system sends an HTTP request to a Scrydon-generated URL.
The Webhook block generates a unique HTTP endpoint. Any external service that can send an HTTP POST request can trigger your workflow.
How it works
- Add a Webhook block to your workflow.
- A unique webhook URL is generated for that block — copy it from the block's Trigger Link field.
- Configure your external service (GitHub, Stripe, any custom system) to POST to that URL.
- When the request arrives, the workflow starts and the request body, headers, method, and query parameters are injected as block outputs.
The editor registers the webhook after its pending changes finish saving. Until the server confirms registration, the Trigger Link remains empty instead of showing a placeholder URL. If registration fails, the block displays an error with a retry action. Trigger-managed webhooks are part of the block lifecycle; remove the trigger block instead of deleting its webhook separately.
Testing in a writable environment
You don't need to deploy or promote to test a webhook. In any writable environment, calling the webhook URL runs the live/draft workflow — exactly what's on the canvas — so you can iterate and test end to end as you build.
In any read-only environment, the webhook runs the deployed snapshot instead and requires an active deployment version. Environment names such as Development, Testing, Staging, and Production are conventions chosen by your organization, not fixed platform roles. Each environment has its own webhook URL. See Triggers → Environments and testing for the full model.
Available variables
Reference the incoming request in downstream blocks using the block's name as the prefix:
| Variable | Description |
|---|---|
<webhook1.payload> | Full request body (parsed JSON or raw string) |
<webhook1.headers> | Request headers as a JSON object |
<webhook1.method> | HTTP method (POST) |
<webhook1.query> | Query string parameters as a JSON object |
Replace webhook1 with whatever name you gave the block.
Authentication
Generic webhook endpoints accept only POST. In the block's Authentication field, choose one of these modes:
Request bodies are limited to 10 MiB (10,485,760 bytes). Larger requests return 413 Payload Too Large and do not start the workflow.
| Mode | Block configuration | Incoming request |
|---|---|---|
| None | No additional fields | No authentication header is required. This is the default. |
| Static Header | Header Name and Header Value | Send the configured header with the exact configured value. Header names are case-insensitive; values are case-sensitive. |
| HMAC Signature | HMAC Header, HMAC Secret, and HMAC Algorithm | Send an HMAC of the exact request-body bytes in the configured header. |
| URL Token | Token Parameter (optional, defaults to token) and Token Value | Send the token as a query parameter, or as Authorization: Bearer <token>. |
URL Token is the weakest mode — reach for it last. A credential in a URL
reaches reverse-proxy access logs, browser history, and Referer headers,
none of which Scrydon controls. It exists for producers that can only be
handed a URL and cannot set a header or sign a body; for that class the only
alternative is None, i.e. no authentication at all. If your producer can
send headers, use HMAC Signature or Static Header instead — and note
that URL Token also accepts the token via Authorization: Bearer, so you can
adopt the mode without ever putting the secret in a URL.
Scrydon redacts the configured token parameter from <webhook1.query> and
from run logs. It cannot redact an upstream proxy's access log.
URL token
# As a query parameter — for producers that only accept a URL
curl -X POST "https://app.scrydon.com/api/webhooks/trigger/{path}?token=$WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"event": "order.created", "orderId": "42"}'
# Same credential, same mode, sent as a header instead
curl -X POST "https://app.scrydon.com/api/webhooks/trigger/{path}" \
-H "Authorization: Bearer $WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"event": "order.created", "orderId": "42"}'Use a workspace-secret reference such as {{GENERIC_WEBHOOK_TOKEN}} for Token
Value, exactly as with the other modes.
A malformed Token Parameter is rejected as invalid configuration rather than silently falling back to the default — a parameter name that could never match the incoming request would mean the credential is never checked while the request still reports as authenticated.
Before exposing <webhook1.headers> to the workflow, Scrydon redacts the configured authentication header and standard credential-bearing headers such as Authorization, Proxy-Authorization, Cookie, and Set-Cookie.
Use a Scrydon workspace-secret reference such as {{GENERIC_WEBHOOK_TOKEN}} for Header Value or {{GENERIC_WEBHOOK_HMAC_SECRET}} for HMAC Secret. Scrydon resolves the reference when authenticating the request. A missing or unavailable reference is rejected.
The password-style fields only mask their contents in the editor. A literal value is stored as plaintext in the workflow JSON. Use a workspace-secret reference so the credential remains behind the Scrydon secret vault.
Static header
For example, configure Header Name as X-Webhook-Token and Header Value as {{GENERIC_WEBHOOK_TOKEN}}, then send the resolved value:
curl -X POST "https://app.scrydon.com/api/webhooks/trigger/{path}" \
-H "Content-Type: application/json" \
-H "X-Webhook-Token: $WEBHOOK_TOKEN" \
-d '{"event": "order.created", "orderId": "42"}'HMAC signature
Scrydon computes the HMAC over the exact bytes received, before JSON parsing, text decoding, normalization, or reserialization. Whitespace, property order, Unicode encoding, and a trailing newline therefore change the signature.
The supported algorithms are sha1, sha256, and sha512. Use sha256 unless your caller requires another supported algorithm. The signature header accepts either a bare hexadecimal digest or an algorithm-prefixed digest:
<hex-digest>
sha256=<hex-digest>When a prefix is present, it must match the configured algorithm. Hexadecimal digits are case-insensitive. This example signs and sends exactly the bytes held in body:
body='{"event":"order.created","orderId":"42"}'
signature="$(printf '%s' "$body" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -hex | awk '{print $NF}')"
curl -X POST "https://app.scrydon.com/api/webhooks/trigger/{path}" \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=$signature" \
--data-binary "$body"Every authentication failure—missing or wrong headers, malformed signatures, invalid configuration, or unavailable secrets—returns the same response and does not start the workflow:
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
Cache-Control: no-store
UnauthorizedHMAC authenticates the body and possession of the shared secret, but it does not prevent replay. A caller can resend a previously valid body and signature because this mode has no timestamp or nonce.
Vendor-specific triggers
For services with a dedicated Scrydon integration (GitHub, Microsoft Graph, Atlassian, etc.), prefer the vendor's trigger block over the generic Webhook block. Vendor triggers parse and validate the event payload automatically and surface typed variables.
See Vendors for the full list of integrations with trigger support.
Responding with the workflow result
By default a webhook acknowledges immediately with 200 {"message":"Webhook processed"} and the workflow runs in the background. Enable Wait for Completion on the block to respond with the result instead:
{ "executionId": "…", "status": "completed", "outputs": { "response": { … } } }A Response block's output appears under outputs. If the run exceeds 30 seconds the request returns 202 with { "executionId", "status": "running" } — the execution continues, and the id lets you follow it.
Leave this off unless the caller expects it. Webhook producers are usually machines with short client timeouts — Keel's is 5 seconds, and it treats a slow reply as a delivery failure and retries, so a synchronous response can turn one event into a retry storm. The immediate acknowledgement exists for that reason.