Skip to main content
The most common cause is parsing the JSON body before hashing. The signature is computed over the raw bytes we sent, not over a re-serialized object.
  • Node / Express — mount express.raw({ type: 'application/json' }) on the webhook route so req.body stays a Buffer.
  • Python / Flask — use request.get_data(), not request.json.
  • Go — read r.Body before any decoder touches it.
Re-reproduce the signature yourself with the openssl one-liner on the Verify signatures page. If your computed value matches Quippy’s but string equality fails, you probably have leading/trailing whitespace in the header or a case-mismatched hex digest.
Your receiver’s signing secret is either missing from the new environment or was rotated in Quippy without updating your secret manager. Check:
  • Your receiver’s environment has the whsec_… value, not a placeholder.
  • The secret in Quippy (Webhooks → endpoint detail) hasn’t been rotated since the value your receiver is using.
Your endpoint is doing synchronous work that exceeds the 10-second dispatch timeout. Return 2xx immediately (after signature verification) and process the event on a background queue. Common culprits: synchronous LLM calls, wide database joins, downstream third-party API calls without a timeout.
Open the endpoint’s detail page in the admin portal, find the delivery in the log, and click Replay. The attempt counter resets and a fresh delivery runs immediately. See Retries and delivery for the API equivalent.
grading.done is listed as a valid event type but is not yet emitted. See the note on Event catalog → grading.done — this is tracked and will ship in a future release.
Still stuck? Include the X-Quippy-Delivery-Id from a failing delivery in your support message so we can trace it end-to-end.