Webhooks
Sending each response to your own endpoint, signed.
What gets sent
A POST with the whole response as JSON: the answers keyed by question reference, the form, and the metadata.
Verifying it came from us
Each request carries an id, a timestamp and a signature. The signature is an HMAC-SHA256 over the id, the timestamp and the raw body, using the secret shown when you create the webhook.
Verify the signature against the raw body bytes, not a re-serialised object — JSON round-tripping changes the bytes and the signature won't match.
Reject anything with a timestamp more than five minutes old. That's what stops a captured request being replayed.
When it fails
Delivery is queued and retried with an increasing gap between attempts. Every attempt, including failures and the reason, is on the form's delivery log, and you can replay one by hand at any point.
A 4xx response other than 429 is treated as permanent and isn't retried — if the endpoint says the request is wrong, sending it again won't help.