Gareth Wilson Gareth Wilson

Guide to Bridge API Webhooks: Features and Best Practices

Published


Bridge API webhooks notify your systems about open-banking activity: an item (bank connection) is refreshed, an account is created or updated, a payment transaction changes. If you're building on Bridge API's aggregation platform, webhooks are how you react to banking data changes without polling.

This guide covers how Bridge API webhooks work, the events you'll handle, how to verify the BridgeApi-Signature, secret rotation, and the best practices for production.

This is Bridge API (bridgeapi.io), the open-banking aggregator by Bankin'/Bridge. It is a different company and API from bridge.xyz (the stablecoin platform), which has its own guide and a completely different (RSA) signature scheme. Make sure you're on the right one.

What are Bridge API webhooks?

Bridge API webhooks are HTTP POSTs delivered to a callback URL you configure in the dashboard, each signed with an HMAC-SHA256. The BridgeApi-Signature header carries one or more scheme-prefixed values, for example v1=E5637CDB... (hex, uppercase). You verify the v1= value over the raw body with the webhook's signing secret.

Bridge API webhook features

FeatureDetails
ConfigurationBridge dashboard (admins only): callback URL, name, events; max 10 webhooks per app
Signature headerBridgeApi-Signature, one or more scheme=value entries (e.g. v1=<hex>)
Signature schemeHMAC-SHA256 over the raw body, hex uppercase; extract the v1= value
SecretAuto-generated per webhook, shown once; 24h dual-secret window on rotation
Source IPs63.32.31.5, 52.215.247.62, 34.249.92.209 (use X-Forwarded-For behind a proxy)
ResponseKeep response bodies under 10 KB
Retries1-2 days with exponential backoff on non-200/slow
SDKNone

Common events

Bridge API event names are lowercase resource.action (some three-segment):

EventFires when
item.refreshedAn item (bank connection) is refreshed
item.createdAn item is created
item.account.createdAn account under an item is created
item.account.updatedAn account under an item is updated
payment.transaction.createdA payment transaction is created
user.deletedA user is deleted

Note the three-segment item.account.* form. A "Send a test" button in the dashboard emits TEST_EVENT. Consult Bridge API's reference for the full list.

Setting up Bridge API webhooks

Configure webhooks in the Bridge dashboard (admins only): callback URL, name, and selected events (max 10 webhooks per app). The signing secret is auto-generated and shown once at creation or rotation, capture it. Optionally allowlist the fixed source IPs (using X-Forwarded-For if you're behind a proxy), and keep your response bodies under 10 KB.

Securing Bridge API webhooks

The BridgeApi-Signature header can hold multiple scheme-prefixed values. Extract the v1= value specifically (ignore other schemes, this guards against downgrade attacks), compute an HMAC-SHA256 with the webhook's signing secret over the raw body, hex-encode it (uppercase), and constant-time-compare. During rotation, up to two signatures may be present; accept a match against either.

const crypto = require("crypto");

// One or two current secrets (24h overlap on rotation)
const SECRETS = (process.env.BRIDGEAPI_WEBHOOK_SECRETS || "").split(",");

function verify(rawBody, signatureHeader) {
  // Extract only the v1= signatures (ignore other schemes)
  const v1Sigs = (signatureHeader || "")
    .split(",")
    .map((s) => s.trim())
    .filter((s) => s.startsWith("v1="))
    .map((s) => s.slice("v1=".length));

  return SECRETS.some((secret) => {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(rawBody)
      .digest("hex")
      .toUpperCase();
    return v1Sigs.some((sig) => {
      const a = Buffer.from(expected);
      const b = Buffer.from(sig.toUpperCase());
      return a.length === b.length && crypto.timingSafeEqual(a, b);
    });
  });
}

app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  if (!verify(req.body, req.headers["bridgeapi-signature"])) {
    return res.sendStatus(401);
  }

  res.sendStatus(200); // acknowledge fast
  processQueue.add(JSON.parse(req.body)); // process asynchronously
});

The same check in Python:

import hashlib
import hmac
import os

SECRETS = os.environ.get("BRIDGEAPI_WEBHOOK_SECRETS", "").split(",")


def verify(raw_body: bytes, signature_header: str) -> bool:
    v1_sigs = [s.strip()[3:] for s in (signature_header or "").split(",") if s.strip().startswith("v1=")]
    for secret in SECRETS:
        expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest().upper()
        if any(hmac.compare_digest(expected, s.upper()) for s in v1_sigs):
            return True
    return False

Bridge API webhook limitations and pain points

Extract v1= to avoid downgrade

The Problem: The BridgeApi-Signature header can carry multiple scheme-prefixed values. Verifying whatever's first (or a weaker scheme) opens a downgrade attack.

Why It Happens: The header is designed to carry multiple schemes.

Workarounds:

  • Extract the v1= value specifically and verify that; ignore other schemes.

How Hookdeck Can Help: Hookdeck verifies the correct scheme at the edge, so your app isn't exposed to downgrade.

Uppercase hex and secret rotation

The Problem: The hex is uppercase, and rotation puts up to two active secrets/signatures in play for 24 hours. Lowercase comparison or checking only one secret fails valid deliveries.

Why It Happens: Bridge API uses uppercase hex and overlaps secrets on rotation.

Workarounds:

  • Compare uppercase, and accept a match against either secret/signature during the 24h window.

How Hookdeck Can Help: Hookdeck handles rotation and encoding at the edge. See our guide to webhook idempotency.

Events for already-deleted users/items

The Problem: You can receive webhooks for users or items that are already deleted. A handler that assumes the referenced resource still exists errors out.

Why It Happens: Delivery and deletion race; Bridge API delivers defensively.

Workarounds:

  • Handle missing resources gracefully (treat a 404 on follow-up as expected).

How Hookdeck Can Help: Hookdeck durably queues events so you can process (or skip) them at your own pace.

Source IPs and response size

The Problem: Deliveries come from fixed IPs (which you may need X-Forwarded-For to see behind a proxy), and responses must stay under 10 KB.

Why It Happens: Bridge API uses a fixed egress and caps response size.

Workarounds:

  • Allowlist the IPs (via X-Forwarded-For behind a proxy) and keep responses small.

How Hookdeck Can Help: Hookdeck provides a stable ingestion URL and a compact acknowledgement, so IP and response-size handling are managed for you.

Best practices

Verify the v1= uppercase-hex signature over the raw body

Extract v1=, HMAC-SHA256 with the webhook secret over the raw body, uppercase hex, and compare in constant time. Accept either secret during rotation.

Confirm you're on Bridge API, not bridge.xyz

They're different companies with different schemes (HMAC here, RSA there).

Handle deleted resources and acknowledge fast

Treat missing users/items as expected, return 200 quickly, and process off a queue. See why to process webhooks asynchronously.

Allowlist IPs and keep responses small

Restrict to the fixed source IPs and keep response bodies under 10 KB.

Make Bridge API webhooks production-ready

Hookdeck verifies BridgeApi-Signature, handles rotation, deduplicates, and durably queues every event

Conclusion

Bridge API (bridgeapi.io) webhooks are verified with a BridgeApi-Signature HMAC-SHA256 over the raw body, extracting the v1= uppercase-hex value (to prevent downgrade), with a 24-hour dual-secret rotation window and fixed source IPs. Verify the v1= value, handle rotation and already-deleted resources, and don't confuse this with bridge.xyz.

Hookdeck verifies the signature, handles rotation, deduplicates, and durably queues every event at the edge, so your app only ever processes verified, unique events.

Get started with Hookdeck for free and handle Bridge API webhooks reliably in minutes.


Gareth Wilson

Gareth Wilson

Product Marketing

Multi-time founding marketer, Gareth is PMM at Hookdeck and author of the newsletter, Community Inc.