Webhooks

Subscribe to real-time events across Checkout and Payout Embed instead of polling. Endpoints are managed from your Developer Portal or the API below.

Manage endpoints

Endpoint management is session-authenticated (your own Blitz login), not API-key-based — manage these from the Developer Portal in your dashboard, or call the API directly if you're automating setup.

POST/api/commerce/webhooks/endpoints

Create an endpoint. Starts on probation — see Retries below.

create-endpoint.sh
curl -X POST https://api.nest.useblitz.co/api/commerce/webhooks/endpoints \
  -H "Authorization: Bearer <your Blitz session>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourstore.com/webhooks/blitz",
    "eventTypes": ["checkout.completed", "payout_embed.session.completed"]
  }'
GET/api/commerce/webhooks/endpoints
PATCH/api/commerce/webhooks/endpoints/:id

Disable/re-enable, or update which event types it's subscribed to.

DELETE/api/commerce/webhooks/endpoints/:id

Permanently removes the endpoint and its delivery history.

POST/api/commerce/webhooks/endpoints/:id/test

Sends a real test event — the fastest way to move a new endpoint off probation.

Up to 10 endpoints per company.

Event types

  • checkout.completed — a Checkout order was paid.
  • payout_embed.session.created, .claimed, .completed, .failed, .expired, .cancelled — the full lifecycle of a Payout Embed session.

Split event types are not available yet.

Verifying a delivery

Every delivery carries four headers: X-Blitz-Event, X-Blitz-Signature, X-Blitz-Timestamp, and X-Blitz-Delivery-Id (a stable id you can use to de-duplicate retried deliveries). The signature is an HMAC-SHA256 over {timestamp}.{payload}, keyed by your company's signing secret — one secret shared across every endpoint you own, visible and rotatable from the Developer Portal.

verify.ts
import crypto from "node:crypto";

function verify(req, signingSecret) {
  const timestamp = req.headers["x-blitz-timestamp"];
  const signature = req.headers["x-blitz-signature"];
  const canonicalPayload = JSON.stringify(req.body); // must match Blitz's canonical JSON
  const expected = crypto
    .createHmac("sha256", signingSecret)
    .update(`${timestamp}.${canonicalPayload}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  );
}
Rotating your signing secret invalidates the old one immediately — there is no grace window. Update your receiver before you rotate, not after.

Retries

A failed delivery retries on a fixed backoff schedule: 5 minutes, 15 minutes, 1 hour, 1 day, 3 days, 7 days. A new endpoint starts on probation (2 attempts) until it receives its first real 2xx — either from a live delivery or a manual test event — after which it gets the full 6-attempt schedule. Return a 2xxas soon as you've durably recorded the event; do your slow processing asynchronously afterward.