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 useSayweek-Signature.
Verifying the signature
- Read the raw request body exactly as it arrived (don't parse and re-serialise it).
- Split the
Sayweek-Signatureheader:tis the timestamp,v1the signature (during a secret rotation there can be severalv1values – any match is enough). - Compute the HMAC-SHA256 with your signing secret over
t.body(the timestamp, a dot, then the raw body), as hex. - Compare in constant time and reject the request if it doesn't match or if
tis 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,429and every5xx; any other4xxis 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.
Was this article helpful?
Related articles
- Webhooks (n8n and your own server)Signed JSON to your URL on every event you pick – with retries, a delivery log and a test button.
- Developer portal: reference, try-it console, Postman, clientsThe /developers page has the full API reference, lets you try calls with your own account, and offers the Postman collection.
- REST API: API keys and scopesCreate an API key, understand the read / write / approve scopes, the main endpoints and how to revoke a key.
- Developer tools: API, webhooks, MCPWhat Sayweek offers developers and automation: REST API, signed webhooks, Zapier, Make, Claude and ChatGPT (MCP) and an iCal link.