Activepieces webhook authentication failed run: Sume signature
Activepieces 0.92 shows a failed run when webhook authentication fails. Sume sends an HMAC signature header you verify yourself in a code step.

Activepieces release notes say a failed webhook authentication now shows a failed run and stops sync flows (#14954). Sume does not authenticate to Activepieces that way: it signs each delivery with HMAC SHA 256 and sends x-sume-webhook-signature: sume-v1=<hex_signature>. Verifying it is a step you write, then you fail the run when it does not match.
The Activepieces line is from its releases page; I did not read how its built-in authentication is configured, so this post does not describe it. Signature details are from Sume's Webhooks docs, read 2026-09-30.
What does Sume sign?
When signing is configured, Sume signs the raw JSON body over <timestamp>.<raw_body>. Two headers arrive: x-sume-webhook-timestamp and x-sume-webhook-signature. During a secret rotation the signature header carries one sume-v1= entry per live secret, newest first, comma separated; accept the delivery if any entry matches.
| Input | Value |
|---|---|
| Signed string | <timestamp>.<raw_body> |
| Algorithm | HMAC SHA 256, hex digest |
| Header format | sume-v1=<hex_signature> |
| Replay window | Reject outside your tolerance; five minutes is the suggested default |
| Secret env name | SUME_COM_WEBHOOK_SIGNING_SECRET |
What should the verifier look like?
The docs ship a TypeScript verifier. The sketch below is a shorter single-entry version; use the docs version if you rotate secrets. It must have the raw body, not re-serialized JSON, and it refuses an empty secret.
import crypto from "node:crypto";
export function verify(raw: string, ts: string, header: string, secret: string) {
if (!secret) return false;
const t = Number(ts);
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const want = Buffer.from(
"sume-v1=" + crypto.createHmac("sha256", secret).update(t + "." + raw).digest("hex"),
);
return header.split(",").some((e) => {
const got = Buffer.from(e.trim());
return got.length === want.length && crypto.timingSafeEqual(got, want);
});
}How do I make a failed check visible?
Throw an error from the code step when verify returns false. Given the release note, whether Activepieces then marks the run failed in your version is something to confirm with a test delivery. If it does not match, compare x-sume-webhook-secret-fingerprint on the delivery with the fingerprint beside the secret in the dashboard; neither side sends the secret itself.
What happens to a rejected delivery?
Sume treats non-2xx responses as failures and retries: up to 10 attempts, a fixed 30s delay by default, 10s timeout per attempt. Keep status_url polling as a fallback, as in the sync webhook 408 case.
Sources
Related posts
More in Integrations
- CapCut Codex plugin plus Sume hosted MCP in one session
CapCut's Codex plugin drafts and edits in chat; Sume's hosted MCP at mcp.sume.com generates media. Here is what each does and how files pass between them.
- Copilot mcp-config.json example: a Sume remote entry
A Copilot mcp-config.json example for Sume: an http entry at mcp.sume.com/mcp with an x-api-key header and a tools list. Global file vs workspace .mcp.json.
- Hedra MCP for Claude, and how Sume's hosted MCP connects
Hedra's MCP and CLI let Claude and other agents generate images, video and audio. Sume's hosted MCP lives at mcp.sume.com/mcp with write and paid gates.
- HeyGen translation SRT captions vs Sume burned-in captions
HeyGen now generates caption sidecars for every translation and lipsync job. Sume burns captions into the video and does not accept SRT as input.
Written by Sume