Agent skill

Bump.sh Webhooks Skill

Receive and verify Bump.sh webhooks. Use when setting up Bump.sh webhook handlers, debugging X-Bump-Signature-256 signature verification, or reacting to API documentation structure changes (the {api, diff} payload sent when a deployment changes your API's structure).

Install this skill

npx skills add hookdeck/webhook-skills --skill bump-sh-webhooks


When to Use This Skill

  • How do I receive Bump.sh webhooks?
  • How do I verify the X-Bump-Signature-256 signature on a Bump.sh webhook?
  • How do I react when Bump.sh detects a structure change in my API documentation?
  • Why is my Bump.sh webhook signature verification failing?
  • Where do I find the Bump.sh webhook secret token?

Verification (core)

Bump.sh signs the raw request body with HMAC-SHA256, keyed on the webhook's secret token, and sends the lowercase hex digest in X-Bump-Signature-256 as sha256=<hex>. Nothing else is signed (no timestamp or id), so there is no replay window to check. Use the secret as UTF-8 bytes as-is, verify over the raw bytes before parsing, validate the digest's format, then compare in constant time. A bare 64-character hex value (no prefix) is also accepted, since the API reference shows one.

Node:

const crypto = require('crypto');

function verify(rawBody /* Buffer */, header, secret) {
  if (!secret || typeof header !== 'string') return false;
  const sig = header.startsWith('sha256=') ? header.slice(7) : header;
  if (!/^[0-9a-fA-F]{64}$/.test(sig)) return false; // exact length + alphabet
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest();
  const received = Buffer.from(sig, 'hex'); // safe: already validated
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

Python:

import hashlib, hmac, re
from typing import Optional

def verify(raw_body: bytes, header: Optional[str], secret: str) -> bool:
    if not secret or not header:
        return False
    sig = header.removeprefix("sha256=")
    if not re.fullmatch(r"[0-9a-fA-F]{64}", sig):
        return False
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
    return hmac.compare_digest(bytes.fromhex(sig), expected)

A missing, empty, malformed or mismatched signature gets 401.

For complete handlers with route wiring, payload handling, and tests, see:

Webhook Payload

Bump.sh has one webhook: it is sent when a deployment changes the structure of a documentation. There is no event-name field or header to switch on. The body is JSON {api, diff}.

FieldMeaning
apiThe documentation the change belongs to
diffThe structural change Bump.sh detected

The page linked from the Bump.sh webhook docs describes the payload in detail; treat every field as untrusted and check its type before reading into it. See references/overview.md.

Important Headers

HeaderDescription
X-Bump-Signature-256sha256= + hex HMAC-SHA256 of the raw body

Environment Variables

BUMP_SH_WEBHOOK_SECRET=your_secret_token   # Shown on the webhook's confirmation screen (Integrations tab)

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 bump-sh --path /webhooks/bump-sh

Hookdeck's Bump.sh source type verifies the same signature (HMAC SHA-256, x-bump-signature-256, hex) before forwarding to your handler.

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 13, 2026

View on GitHub →