whsec_ secret. Verifying the signature proves the request came from Geldstuck and wasn’t altered in transit.
Headers
Every delivery carries two signature headers - a modern one and a legacy fallback. Always verify the modern header; the legacy one exists only for older integrations.| Header | Format | Use |
|---|---|---|
Geldstuck-Signature | t=<unix>,v1=<hmac> | Modern - verify this. |
X-Geldstuck-Signature | Raw HMAC hex | Legacy. |
X-Geldstuck-Event | Event type, e.g. kyc.completed | Convenience - never trust before verifying. |
X-Geldstuck-Webhook-Id | Event ID, e.g. evt_01HX... | Use for idempotency. |
How we compute Geldstuck-Signature
How you verify it
Read the raw body
Do not parse JSON before verifying. The signature is over the exact bytes we sent - any whitespace normalization or key-order change will break it. Use your framework’s raw-body middleware.
Reject stale timestamps
If the timestamp is more than 5 minutes old, reject the request. This prevents replay attacks even if a signature leaks.
Compute the expected HMAC
Build
signedPayload = timestamp + "." + body and HMAC it with your secret.Reference implementation
Rotating the webhook secret
Dual-verify for the grace period
We return both the old and new secrets for 24 hours. Your handler should accept either.
Your verifier should accept a list of valid secrets and return success if any one matches. That way rotations are a one-line config change.