Custom Webhook Trigger
A Custom Webhook gives your flow a unique HTTP URL. When an external system sends a request to that URL, the flow runs with the request's data as input. Webhooks are how you connect AgentFlow to any platform that isn't built in — custom CRMs, form builders, Telegram bots, e-commerce stores, internal tools, or anything that can send an HTTP request.
You configure webhooks on the Start node under Webhooks. Each webhook you add gets its own URL and its own security settings.
Adding it to a flow
On the Start node, open Webhooks, add a webhook, and set Webhook Type to Custom Webhook. Then pick a mode and a verification method.
Dedicated vs Workspace mode
The first choice is Webhook Mode:
| Mode | What it does | Use when |
|---|---|---|
| Dedicated | Creates a unique URL just for this flow. All security and payload settings live on this webhook. | Most integrations — one external system talks to one flow. |
| Workspace | Shares one URL across several flows in the workspace. Incoming requests are routed to flows by filters. | Meta (Instagram/WhatsApp) and any case where one endpoint must fan out to multiple flows. |
Meta integrations require Workspace mode. Instagram and WhatsApp both deliver every event to a single Meta webhook URL, so a shared workspace webhook (with filters) is required to route those events to the right flows. For a purpose-built Meta setup, prefer the dedicated Instagram and WhatsApp triggers instead — they auto-configure everything.
In Dedicated mode you set a Webhook Name (used in the URL and in {{$webhook.<name>.*}} variables), an optional Description, and an Enabled toggle. In Workspace mode you pick an existing workspace webhook (or create a new one) and add Filters — each request must match all filters to trigger the flow.
The webhook URL
A dedicated webhook's URL follows this pattern:
POST /api/v1/webhook/{flowId}/{webhookName}
External systems send an HTTP POST here. The request returns immediately with a chatId and sessionId — the flow then runs in the background. This "fire-and-forget" behavior keeps fast-timing-out platforms happy even when your flow takes seconds to think.
Verification methods
Verification is how Flowera confirms an incoming request really came from your trusted system and not an attacker who guessed the URL. Choose the method your platform supports.
HMAC signature
The platform signs each request body with a shared secret, and Flowera recomputes the signature to confirm it matches. Used by GitHub, Meta, Shopify, and Stripe. Available as HMAC SHA-256 (recommended), SHA-1 (legacy), and SHA-512.
| Field | Description |
|---|---|
| HMAC Secret | The signing secret provided by the sending platform. |
| Signature Header Name | The header carrying the signature (e.g. x-hub-signature-256 for GitHub/Meta, x-shopify-hmac-sha256 for Shopify). |
| Signature Prefix | Optional text before the signature (e.g. sha256= for GitHub). Leave empty if there is none. |
JWT token
Verifies a signed JSON Web Token — common with OAuth-based systems.
| Field | Description |
|---|---|
| JWT Secret/Public Key | The signing secret (for HS algorithms) or public key (for RS algorithms). |
| JWT Algorithm | The signing algorithm: HS256/384/512 or RS256/384/512. |
| JWT Token Location | Where the token sits in the request: Header, Request Body, or Query Parameter. |
| JWT Token Field Name | The field/header holding the token (e.g. authorization). |
Bearer token
Simple shared-token check against the Authorization header.
| Field | Description |
|---|---|
| Bearer Token | The expected secret token. |
| Bearer Token Header Name | The header carrying the token (defaults to authorization). |
Custom header
Checks that a specific header carries an expected value — for example an X-API-Key.
| Field | Description |
|---|---|
| Header Name | The header to check (e.g. x-api-key, x-webhook-token). |
| Expected Header Value | The secret value that header must contain. |
Meta Challenge Verification
Meta (Instagram/WhatsApp) and Slack verify a webhook by sending a one-time GET challenge before they'll deliver events. Turn on Enable Challenge Verification to answer it.
| Field | Description |
|---|---|
| Challenge Parameter Name | The query parameter carrying the challenge value (Meta uses hub.challenge, Slack uses challenge). |
| Verify Token Parameter Name | Optional — the parameter carrying the verify token (Meta uses hub.verify_token). |
| Verify Token Value | The expected verify token, matched against what the platform sends. |
| Challenge Response Mode | Echo returns the challenge value (Meta, Slack); Static returns a fixed string. |
| Static Response Text | The fixed reply text, used only when Response Mode is Static. |
Other verification methods are also available for specialized platforms: Basic Authentication (username + password), Query Parameter (a secret in the URL), and ED25519 Signature (Discord Interactions). There is also a None option — accept every request with no checks — which is strictly for local testing.
Never leave a production webhook on None verification, and avoid Query Parameter where you can — URLs (and their query strings) are often logged along the way. Prefer HMAC or header-based methods.
Reading the payload in your flow
When you paste a sample request into the webhook's Example Payload field, Flowera reads its structure and makes every field available as {{$webhook.<name>.<field>}}. For a webhook named crm receiving { "customer": { "email": "..." } }, you'd use {{$webhook.crm.customer.email}}. The whole raw body is available as {{$webhook.crm.payload.raw}}.
You can also set a Session ID Template (e.g. {{$webhook.crm.senderId}}) so repeat requests from the same customer land in the same conversation. Leave it empty to generate a fresh session per request. See Variables for details.
Testing
- Add an Example Payload on the webhook so the canvas test panel can simulate a real request — your
{{$webhook.<name>.*}}variables then resolve while you build. - Send a real request with
curlor your platform's test button once the flow is deployed:
curl -X POST https://your-flowera-instance.com/api/v1/webhook/FLOW-ID/crm \
-H "Content-Type: application/json" \
-d '{ "message": "I need help with my order", "senderId": "user-123" }'
Tips
- A single Start node can hold multiple webhooks, each with its own name, URL, and security — handy for separating events from different systems.
- Give each webhook a clear name: it appears in the URL and in every
{{$webhook.<name>.*}}variable. - To place a customer's message into chat history, map the payload field to
$question.