Flow.Documentation
AdvancedAPIs

Sign in with a webhook signature (HMAC)

5 steps± 4 minVideoVerified 22 Oct 2026
  1. Step 1 · Open your development environment
  2. Step 2 · A policy with a webhook signature
  3. Step 3 · Attach the policy to the API
  4. Step 4 · Without a signature: 401
  5. Step 5 · With a signature: in

Webhooks from payment providers, web shops and Git platforms (Stripe, Shopify, GitHub) do not sign in with a key, but sign every message: an HMAC over the body with a shared secret, in a header. Flow recalculates that signature itself. You create a policy with a webhook signature and see an unsigned message fail and a signed one get in.

Watch the whole guide as a video5 steps in one film
Step 1 / 5

Open your development environment

In the portal, under Environments, click Development, and there Open. Flow opens in a new tab and you are signed in straight away.

  1. Click Development
Open your development environment · Click Development
  1. Click Open ↗
Open your development environment · Click Open ↗
Step 2 / 5

A policy with a webhook signature

Under Security you create a policy: API key off, Webhook signature on. Fill in which header the sender uses, with which prefix, and the shared secret the sender gave you. The secret can never be read back afterwards.

  1. Click Security
A policy with a webhook signature · Click Security
  1. Click New security policy
A policy with a webhook signature · Click New security policy
  1. In Name, type Payment provider (webhook)
A policy with a webhook signature · In Name, type Payment provider (webhook)
  1. Click API key X-API-Key or Bearer flw_…
A policy with a webhook signature · Click API key X-API-Key or Bearer flw_…
  1. Click Webhook signature HMAC over the body (GitHub, Stripe, Shopify style)
A policy with a webhook signature · Click Webhook signature HMAC over the body (GitHub, Stripe, Shopify style)
  1. In Signature header, type X-Signature
  2. In Prefix, type sha256=
  3. In Secret, type ••••••••
A policy with a webhook signature · In Signature header, type X-Signature; In Prefix, type sha256=; In Secret, type ••••••••
  1. Click Save policy
A policy with a webhook signature · Click Save policy
A policy with a webhook signature · A consumer gets in with Webhook signature.
Step 3 / 5

Attach the policy to the API

Open the API, choose the policy and save. From now on the endpoint POST /webhook only receives messages with a matching signature. A signature proves who sent it, but grants no permissions: an endpoint that demands a permission (scope) does not let a webhook in.

  1. Click Explorer
Attach the policy to the API · Click Explorer
  1. Click the API
Attach the policy to the API · Click the API
  1. In Security policy, choose Payment provider (webhook)
Attach the policy to the API · In Security policy, choose Payment provider (webhook)
  1. Click Save API
Attach the policy to the API · Click Save API
Attach the policy to the API · In plain language: only with a webhook signature.
Step 4 / 5

Without a signature: 401

In Test APIs you choose the endpoint and send a message without a signature, like someone imitating the webhook. The gateway answers 401 and the workflow does not run.

  1. Click Test APIs
Without a signature: 401 · Click Test APIs
  1. Click the endpoint
Without a signature: 401 · Click the endpoint
  1. Click None
Without a signature: 401 · Click None
  1. Click Code
Without a signature: 401 · Click Code
  1. In Body, type {"event": "payment.paid", "order": "1042", "amount": 86}
Without a signature: 401 · In Body, type {"event": "payment.paid", "order": "1042", "amount": 86}
  1. Click ▶ Send
Without a signature: 401 · Click ▶ Send
Without a signature: 401 · 401: signature missing.
Step 5 / 5

With a signature: in

The sender calculates the HMAC-SHA256 over exactly the body it sends, with the shared secret, and puts it in the header with the prefix. Here you imitate that: the header X-Signature with the right value. Now the gateway answers 200.

  1. Click None
With a signature: in · Click None
  1. Click + Add
With a signature: in · Click + Add
  1. In Name, type X-Signature
  2. In Value, type sha256=2bc69809301678fea177a83dca487f7ba8de66146ea1f8c1e59933fd546c3599
With a signature: in · In Name, type X-Signature; In Value, type sha256=2bc69809301678fea177a83dca487f7ba8de66146ea1f8c1e59933fd546c3599
  1. Click Code
With a signature: in · Click Code
  1. In Body, type {"event": "payment.paid", "order": "1042", "amount": 86}
With a signature: in · In Body, type {"event": "payment.paid", "order": "1042", "amount": 86}
  1. Click ▶ Send
With a signature: in · Click ▶ Send
With a signature: in · 200: the signature matches.

This guide was carried out step by step on 22 Oct 2026 by an automated test on Flow (version 3e563176).