Verify each webhook signature before processing the payload. PigeonFiles signs the timestamp and raw request body with the endpoint’s secret.
How PigeonFiles signs webhooks
Every webhook delivery includes these headers:
x-pigeonfiles-signature: contains a timestamp and HMAC-SHA256 signature.x-pigeonfiles-delivery-id: a unique identifier for this delivery.x-pigeonfiles-event: the event type (e.g.,submission.created).
The signature header has the format:
t=1750550400,v1=5d3a...c9f2
tis the Unix timestamp (seconds) when PigeonFiles generated the signature.v1is the hex-encoded HMAC-SHA256 digest.
Verification steps
To verify a webhook delivery:
-
Extract the timestamp and signature. Parse the
x-pigeonfiles-signatureheader. Split on,to get thet=andv1=components. -
Build the signed payload. Concatenate the timestamp, a literal
., and the raw request body:{timestamp}.{raw_body} -
Compute the expected signature. Use your signing secret to compute an HMAC-SHA256 digest of the signed payload.
-
Compare. Use a constant-time comparison to check your computed signature against the
v1value from the header. If they match, the request is genuine and unmodified. -
Check the timestamp (recommended). Compare the
tvalue against the current time. Reject requests where the timestamp is too old (for example, more than five minutes) to guard against replay attacks.
Handling retries and duplicates
PigeonFiles retries failed deliveries. Your endpoint may receive the same event more than once.
To handle duplicates safely:
- Use the
x-pigeonfiles-delivery-idheader to identify repeated deliveries of the same event. - Design your processing to be idempotent, producing the same result whether the event is processed once or multiple times.
- Return a 2xx response quickly. If your processing takes time, acknowledge the request first and process the event asynchronously.
Rotating the signing secret
If a signing secret is compromised or you want to rotate it as a precaution:
- Go to Settings > Integrations and open the webhook endpoint.
- Click Rotate signing secret.
- Copy the new secret immediately, it will not be shown again.
- Update your server to verify with the new secret.
If your endpoint may still receive in-flight retries signed before rotation, keep the change coordinated with your deployment so valid requests are not rejected during the switch.
Troubleshooting
Signature mismatch. Confirm you are using the raw request body (not a parsed/re-serialized version). JSON parsing and re-encoding can change whitespace or key order, which changes the digest.
Timestamp too old. If your server clock is significantly different from UTC, the timestamp check may reject valid requests. Synchronize your server clock with NTP.
Wrong signing secret. If you rotated the secret, make sure your server is using the current secret. The previous secret is not recoverable from PigeonFiles.
Next steps
- Create a webhook endpoint, set up your first endpoint if you haven't already.
- Create API token, access submission data directly through the API.
Frequently asked questions
What happens if I don't verify signatures?
Your endpoint would accept any POST request that matches the URL, including forged requests. Signature verification confirms that the request came from PigeonFiles and the payload was not modified in transit.
Can I rotate the signing secret?
Yes. In Settings > Integrations, open the webhook endpoint and click Rotate signing secret. Copy the new secret immediately, it will not be shown again. Update your server to verify with the new secret before the next delivery.
