Snapcaster sends these signature headers with every webhook.

X-Snapcaster-Timestamp string required

Unix seconds when the request was signed; reject if outside a ±5 minute window.

X-Snapcaster-Signature string required

sha256= + lowercase hex of HMAC_SHA256(signingSecret, timestamp ‖ raw request body).

The signed message is the timestamp followed by the raw request body, byte for byte, with no delimiter between them. Verify before you parse the JSON, because re-serializing a parsed body changes its bytes and invalidates the signature.

Node.js raw-body signature verification
const crypto = require('node:crypto');

function verifySnapcasterWebhook(rawBody, headers, signingSecret) {
  const timestamp = headers['x-snapcaster-timestamp'];
  const signature = headers['x-snapcaster-signature'];

  if (typeof timestamp !== 'string' || typeof signature !== 'string') return false;
  if (!/^\d+$/.test(timestamp) || !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;

  const timestampSeconds = Number(timestamp);
  if (!Number.isSafeInteger(timestampSeconds)) return false;
  if (Math.abs(Date.now() / 1000 - timestampSeconds) > 300) return false;

  const expected = Buffer.from(
    'sha256=' +
      crypto.createHmac('sha256', signingSecret).update(timestamp).update(rawBody).digest('hex'),
  );
  const received = Buffer.from(signature);

  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

Build a webhook receiver shows the whole receiver around this function, including how to read the raw body.

  1. Capture the raw body bytes.
  2. Reject a missing or malformed timestamp or signature.
  3. Reject a timestamp outside the five-minute replay window.
  4. Recompute HMAC-SHA256 over timestamp || rawBody with the environment’s per-platform signing secret.
  5. Compare the complete prefixed signature in constant time.
  6. Parse JSON and deduplicate the delivery on event_id.

If verification fails, return a non-2xx response so Snapcaster retries the delivery.

The signing secret differs between sandbox and production, and each environment has one live secret, so rotating the signing secret is a cutover. Do not verify webhooks with a seller’s marketplace API key.

To have Snapcaster send your endpoint one signed webhook.test event, call POST /webhooks/test with a new UUID Idempotency-Key. Snapcaster signs and retries it like every other event, and the response’s event_id is the one the delivery carries. The test works for every subscription, in sandbox and in production, and changes no order and no stock. A platform may send five test events a minute, and past that the call returns RATE_LIMITED with Retry-After. WEBHOOK_ENDPOINT_NOT_REGISTERED means Snapcaster has not registered your receiver in this environment yet.

Path A continues with Keep stock in sync, and Path B skips ahead to Receive and ship orders.

Need help?

Email Marketplace support.

The email includes this page and selects sandbox as the environment. Update it if you need help with production.

Never include an API key or signing secret in the message.