The signature header
Each delivery includes anX-Fanvue-Signature header:
tis a Unix timestamp (seconds since epoch) recording when Fanvue signed the request.v0is the HMAC-SHA256 signature of the signed payload, encoded as a hexadecimal string.
Get your signing secret
The signature is computed with a per-app signing secret. Find it in the Fanvue Developer Area:How verification works
Recompute the signature yourself and check it matches what Fanvue sent.Parse the header
Split
X-Fanvue-Signature on the comma and read t (the timestamp) and v0 (the signature). If either is missing, reject the request.Reconstruct the signed payload
Concatenate the timestamp, a period, and the raw request body:
{timestamp}.{body}. Use the exact bytes Fanvue sent. If you parse the JSON first and re-serialize it, the bytes change and the signature will not match.Compute the expected signature
Run HMAC-SHA256 over the signed payload using your signing secret, then hex-encode the result.
Compare in constant time
Compare your computed signature against
v0 with a timing-safe comparison (crypto.timingSafeEqual in Node, hmac.compare_digest in Python). A plain == can leak the secret through timing differences.Code sample
Both samples take the raw request body and theX-Fanvue-Signature header value, and return whether the request is authentic.
- Node.js
- Python
When verification fails, respond with
401 and do not process the payload. When it succeeds, persist the event and return a 2xx as described in the Webhooks Overview.Test it without waiting for a real event
Use the Test action in the webhook’s … menu (in the Events & Endpoints list) to send a sample payload to your endpoint. It carries a realX-Fanvue-Signature header, so a passing test confirms your verification logic works end to end.