Skip to main content
Webhooks let an external system trigger a Metal workflow when something happens on its side. Instead of polling, your system makes a single POST to a workflow’s webhook trigger, and Metal starts a run.

How workflow webhooks work

Each workflow can be configured with a webhook trigger that exposes a unique URL with a per-workflow slug:
When your system posts to this URL, Metal verifies the request and starts a workflow run with the payload as input.
1

Add a webhook trigger to a workflow

In the Metal app, configure the workflow with a webhook trigger. Metal generates the slug and a secret used to verify incoming requests.Choose how the sender will authenticate:
  • Shared secret (default) — the sender includes the secret verbatim in a header. Easiest to set up; use it when you control both ends.
  • HMAC-SHA256 — the sender signs the raw request body with the secret and sends the digest in a header. Use it when integrating with a provider that signs payloads (for example, GitHub’s X-Hub-Signature or Fireflies).
You can also override the Signature header name. Leave it blank to use the scheme default (X-Metal-Webhook-Secret for shared secret, X-Hub-Signature for HMAC-SHA256).
2

Call the webhook from your system

POST your event payload to the workflow’s webhook URL, signed according to the configured scheme.Shared secret:
HMAC-SHA256:
3

Metal starts a run

The incoming payload becomes the run’s input, available as webhook.payload, with webhook.headers and webhook.query also exposed. Track the resulting run with GET /v1/workflow-runs/{id}.

Securing webhook triggers

Each webhook trigger has a secret and a signature scheme that together determine how Metal authenticates inbound requests. Anyone who can reach the URL with a valid signature can start a run, so treat the slug and secret like credentials.

Shared secret (default)

The sender includes the trigger’s secret as-is in a header. Metal compares it against the stored secret using a constant-time check.
  • Default header: X-Metal-Webhook-Secret
  • Authorization: Bearer <secret> is also accepted when the default header is in use.
  • Set a custom Signature header on the trigger to require a different header name (for example, X-My-Token). When a custom header is set, the Authorization fallback is disabled.

HMAC-SHA256

The sender computes HMAC-SHA256(secret, raw_request_body) and sends the digest in a header. Metal recomputes the digest from the received body and compares it in constant time. The body must be signed exactly as transmitted — any reserialization will invalidate the signature.
  • Default header: X-Hub-Signature
  • Expected value: sha256=<hex> (GitHub/Fireflies format). A bare hex digest without the sha256= prefix is also accepted.
  • Override the header name on the trigger to match a sender that uses something else (for example, X-Hub-Signature-256).

Example: Fireflies

Fireflies posts events with an X-Hub-Signature header containing sha256=<hex> of the raw body, signed with the secret you configure on their side. Configure the Metal trigger with:
  • Signature scheme: HMAC-SHA256
  • Signature header: leave blank (defaults to X-Hub-Signature)
  • Secret: paste the same secret into Fireflies’s webhook settings
Requests Fireflies sends will then verify automatically.

Rotating the secret

Rotate a trigger’s secret with:
After rotating, update the new value on the sender side.
Treat webhook URLs and their secrets like credentials. If a slug or secret is exposed, rotate the secret immediately.

Choosing between webhooks and the API

Use a webhook trigger

When an external system should start a workflow in response to its own events, without managing API keys.

Use the API

When your code already authenticates with Metal and you want to create runs explicitly with POST /v1/workflows/{id}/runs.
Metal also receives inbound webhooks from connected providers (file storage, CRM, and others) to keep data in sync. Those integrations are configured in the app and don’t require any setup in your own code.