hooks.bot Docs / Slack

Slack webhook signature verification

Slack signs each webhook and sends the digest in X-Slack-Signature. When your check fails, one of a small number of steps is wrong — and guessing which is the slow way to find out. Paste the payload, the secret and the header block into the debugger and it rebuilds the signature every way it could plausibly have been made, then names the step that differs. It runs in your browser: the secret never leaves the page.

The scheme

Exactly what Slack signs

FieldValue
HeaderX-Slack-Signature
Signed stringv0:{timestamp}:{body}
AlgorithmHMAC-SHA-256
Digest encodinghex
KeySigning Secret from your app's Basic Information page — not a bot token.
Replay window300s

Official reference: https://api.slack.com/authentication/verifying-requests-from-slack.

Causes

What actually goes wrong

Stripe and Svix both issue secrets that begin whsec_ and derive keys from them completely differently. Stripe uses the whole string, prefix included. Svix and Standard Webhooks strip the prefix and base64-decode the rest. This is the single commonest failure in the category.

Capture it

Get the real bytes, not a copy of a copy

If you are diagnosing from a logged payload you may be debugging the log rather than the webhook. Point Slack at a disposable URL and work from what actually arrived:

curl -X POST https://www.hooks.bot/api/endpoints
# {"url":"https://www.hooks.bot/h/abc…"}

Paste that URL into your Slack webhook settings, trigger an event, and the request appears at https://www.hooks.bot the moment it lands — headers, body and all. Press Diagnose this signature and add your secret.

Or let your agent do it

claude mcp add --transport http hooks-bot https://www.hooks.bot/mcp

Claude Code, Cursor and Codex can create the endpoint, block until the webhook lands, and diagnose it against the captured bytes without you copying anything.

Other providers

Stripe · GitHub · Svix / Standard Webhooks · Shopify · Paddle Billing · Twilio