Skip to content

Webhooks: verifying signatures and retries

How to verify the Sayweek-Signature header in code, how failed deliveries are retried, and when an endpoint gets switched off.

Updated:

Every delivery is a POST request with a JSON body: id (the event ID), event, api_version, created_at, workspace_id and data. The signature proves the request comes from us and wasn't changed on the way.

Headers

  • Sayweek-Signature: t=<unix seconds>,v1=<hex> – the signature.
  • Sayweek-Event-Id – the same on every retry and resend: use it to drop duplicates.
  • X-Sayweek-Event – the event name, e.g. post.published.
  • X-Sayweek-Delivery – the delivery ID (the rows of the Delivery log).
  • X-Sayweek-Signature: sha256=<hex> – the old format for earlier integrations; new code should use Sayweek-Signature.

Verifying the signature

  1. Read the raw request body exactly as it arrived (don't parse and re-serialise it).
  2. Split the Sayweek-Signature header: t is the timestamp, v1 the signature (during a secret rotation there can be several v1 values – any match is enough).
  3. Compute the HMAC-SHA256 with your signing secret over t.body (the timestamp, a dot, then the raw body), as hex.
  4. Compare in constant time and reject the request if it doesn't match or if t is older than 5 minutes (so a captured request can't be replayed later).

In Node.js: createHmac("sha256", secret).update(t + "." + rawBody).digest("hex"), then timingSafeEqual against the v1 value from the header.

In Python: hmac.new(secret.encode(), f"{t}.{raw_body}".encode(), hashlib.sha256).hexdigest(), then hmac.compare_digest against v1.

Retries

  • A 2xx response within 8 seconds counts as delivered – answer quickly and do longer work afterwards.
  • We retry network errors, timeouts, 408, 409, 425, 429 and every 5xx; any other 4xx is final.
  • The pauses: about 1 min, 4 min, 16 min, 1 h, 4 h, then 12 h (with a little random jitter) – at most 8 attempts in total, over roughly a day and a half.
  • If a Zapier, Make or API subscription answers 410 Gone, the subscription is removed.

Switched off automatically

If at least 10 attempts in a row fail for an endpoint and this has been going on for more than a day, the webhook is switched off and the owners get a push notification and an email. A short outage therefore never switches it off. To switch it back on: Settings → All integrations → Webhooks · n8n, then Switch on in the webhook's row – this resets the failure streak. Test sends never count.

Open in Sayweek

Was this article helpful?

Can't find the answer?

Write to us: hello@sayweek.com

Webhooks: verifying signatures and retries – Help center | Sayweek