Skip to main content

Overview

Quo signs every webhook delivery. Before you trust a payload, verify it by checking the signed headers against the raw request body bytes. Each request includes three headers: The signature is HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{raw-body}, encoded as base64.
Verification must use the exact raw request body bytes Quo sent. If your middleware parses or rewrites the JSON body first, verification will fail.

Webhook key format

When you create a webhook, Quo returns a key value prefixed with whsec_. Store it exactly as returned.
  • The whsec_ prefix is part of the canonical format; SDK-based verification accepts it as-is.
  • If you verify manually, strip whsec_ and base64-decode the remainder to get the HMAC key bytes.
You can verify Quo webhook signatures with the svix library — it accepts Quo’s headers and whsec_... key format as-is. Install the library:
Then verify:

Manual verification

If you prefer not to add an SDK dependency, verify with Node’s built-in crypto:

Implementation notes

  • Always verify using the raw request body, before parsing or transforming it.
  • Reject deliveries whose webhook-timestamp is more than a few minutes off from the current time to protect against replay.
  • Store the webhook key (whsec_...) exactly as Quo returns it; do not trim, rewrap, or lowercase it.

Other languages

Any library that supports Quo’s signing scheme — HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{raw-body} with the webhook-* header set and a whsec_... base64 secret — can verify Quo webhooks. The Svix SDKs are a convenient off-the-shelf option across several languages; you can also port the manual example above.