Home Integrations Verify webhook signatures

Verify webhook signatures

Last updated on Nov 06, 2026

Verify each webhook signature before processing the payload. PigeonFiles signs the timestamp and raw request body with the endpoint’s secret.

Webhook endpoint setup. Store the one-time signing secret securely after creation.

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
  • t is the Unix timestamp (seconds) when PigeonFiles generated the signature.
  • v1 is the hex-encoded HMAC-SHA256 digest.

Verification steps

To verify a webhook delivery:

  1. Extract the timestamp and signature. Parse the x-pigeonfiles-signature header. Split on , to get the t= and v1= components.

  2. Build the signed payload. Concatenate the timestamp, a literal ., and the raw request body:

    {timestamp}.{raw_body}
    
  3. Compute the expected signature. Use your signing secret to compute an HMAC-SHA256 digest of the signed payload.

  4. Compare. Use a constant-time comparison to check your computed signature against the v1 value from the header. If they match, the request is genuine and unmodified.

  5. Check the timestamp (recommended). Compare the t value 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-id header 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:

  1. Go to Settings > Integrations and open the webhook endpoint.
  2. Click Rotate signing secret.
  3. Copy the new secret immediately, it will not be shown again.
  4. 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

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.