Skip to content
Docs
flero.ai

Webhook trigger

The Webhook Trigger gives your workflow a public HTTPS URL. Anything that POSTs (or GETs, PUTs, โ€ฆ) to that URL fires a run, with the request body, headers, and query string passed as the trigger payload.

๐Ÿ“ธ Screenshot needed: triggers__webhook-url-copy.png, Webhook Trigger inspector showing the generated URL with a Copy button highlighted, the secret field, and the HTTP method selector.


When to use it

  • Receiving webhooks from external services that don't have a Flero connector (e.g. a custom internal system).
  • Receiving events from services with connectors when you want raw control over the payload.
  • Building an API endpoint backed by a workflow (Flero becomes your serverless function).

For services with a dedicated connector trigger (Stripe, GitHub, Shopify, Slack, โ€ฆ), prefer the connector, it handles signature verification, retry semantics, and event typing for you. See Connector event triggers.


Configuration

Field Notes
Path Auto-generated path suffix (e.g. /webhook/abc123). Click the URL field to view / copy the full HTTPS URL.
HTTP method POST (default), GET, PUT, PATCH, DELETE. Choose one, separate methods need separate Webhook Triggers.
Secret Optional. If set, Flero validates the X-Webhook-Secret header on every incoming request and returns 401 if it doesn't match.
Payload type auto-detect (default), json, form, text, binary. Auto-detect uses the request Content-Type.
Response mode Immediately (returns 200 OK before the workflow runs) or On completion (returns whatever the workflow produces)
Response code The status code returned in Immediately mode (default 200)
Allowed origins Optional CORS allow-list. Use when called from browsers.
Allowed methods For OPTIONS preflight responses
Authentication None (default), Basic, Bearer, API key, applied in addition to the secret

The trigger payload

After the trigger fires, $trigger looks like:

{
  "body":      { /* parsed JSON, or raw string */ },
  "headers":   { "content-type": "application/json", "user-agent": "..." },
  "query":     { "param1": "value", "param2": "value" },
  "method":    "POST",
  "path":      "/webhook/abc123",
  "timestamp": "2026-05-15T10:00:00Z"
}

Use $trigger.body.<field>, $trigger.headers.<header-name>, etc. in downstream nodes.


Activating the webhook

  1. Save the workflow.
  2. Set workflow status to Active (top toolbar status chip โ†’ Active).
  3. Copy the URL from the Webhook Trigger's inspector.
  4. Configure the external service to POST to that URL.

The URL is inert while the workflow is in draft or inactive status, Flero returns 410 with a message saying so.


Testing locally

The Webhook Trigger has a Test webhook button in its inspector. It lets you:

  • Paste a JSON body and headers.
  • Pick the HTTP method.
  • Fire a real request to the URL, which triggers the workflow as if a real external service had posted.

This is the fastest dev loop: tweak the workflow, click Test webhook, inspect the result.

Alternatively, use curl:

curl -X POST https://app.flero.ai/webhook/abc123 \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: your-secret-here" \
  -d '{"orderId": 42, "amount": 99.99}'

Security

Use a secret

Anything POSTing to your URL fires the workflow. If the URL leaks (in logs, in code commits, in screenshots), random traffic can hammer it. The Secret field is the simplest mitigation, only requests with the matching X-Webhook-Secret header succeed.

Signature verification (preferred for HMAC-signing services)

Most webhook providers (Stripe, GitHub, Shopify) sign their payloads with HMAC. Flero won't verify those automatically (the algorithm and header name varies). Add an Encryption/Hashing node right after the trigger:

[Webhook Trigger]
   โ†“
[Encryption: HMAC SHA256 of $trigger.body using $env.STRIPE_SIGNING_SECRET]
   โ†“
[If: result equal $trigger.headers["stripe-signature"]]
   true โ†’ continue
   false โ†’ [Terminal: status=failed]

Rate limiting

Set a workflow-level rate limit (workflow settings โ†’ Trigger options) to bound the worst case.

CORS

For webhooks called from browsers, set Allowed origins to the exact origins you trust. Default is * (allow all), which is fine for server-to-server and unsafe for browser-to-server.


Response modes

Immediate

Flero responds 200 OK as soon as the request is received and queues the workflow run. Caller gets a fast acknowledgement; workflow result is not returned to the caller.

Best for fire-and-forget webhooks (most real webhooks).

On completion

Flero waits for the workflow to finish and returns the result of the Terminal node as the response body. Caller blocks until the workflow completes (or until the per-workflow timeout).

Best for "treat this URL as an API endpoint" patterns. Set workflow timeout appropriately so the caller doesn't hang forever.


Tips & gotchas

  • The URL is stable across versions, version changes don't change the URL. Renaming the Path field does change it; coordinate with the calling system.
  • Payload size limit is 10 MB by default. Larger uploads should be sent to object storage (S3, GCS) directly and reference by URL.
  • Concurrent webhooks all fire, Flero doesn't deduplicate without an idempotency key. Use the Cache idempotency pattern.
  • Replay protection. Some webhook providers include a timestamp + nonce in the signature. Validate both, not just the HMAC, to prevent replay attacks.
  • Dev vs prod URLs. When promoting a workflow from a dev workspace to prod, the URL changes. Update the external service. Or set up two webhooks in the external service (one per environment).


Found something out of date? This page lives in the Flero docs content set.