# 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:

```javascript
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:

```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:
> 
> * [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/bump-sh-webhooks/examples/express/)
> * [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/bump-sh-webhooks/examples/nextjs/)
> * [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/bump-sh-webhooks/examples/fastapi/)

## 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}`.

| Field | Meaning |
| --- | --- |
| `api` | The documentation the change belongs to |
| `diff` | The 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](https://github.com/hookdeck/webhook-skills/blob/main/skills/bump-sh-webhooks/references/overview.md).

## Important Headers

| Header | Description |
| --- | --- |
| `X-Bump-Signature-256` | `sha256=` + hex HMAC-SHA256 of the raw body |

## Environment Variables

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

```

## Local Development

```bash
# 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

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/bump-sh-webhooks/references/overview.md) - What Bump.sh webhooks are and the payload
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/bump-sh-webhooks/references/setup.md) - Registering a webhook and finding the secret token
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/bump-sh-webhooks/references/verification.md) - Signature verification details and gotchas