Skip to main content

Praeto Dispatcher Signature Verification

Praeto Dispatcher signs every outbound webhook so receivers can verify that the request came from Praeto Dispatcher and was not modified in transit. Webhook signing is not optional for production integrations. Customers should reject unsigned or unverifiable webhook requests.

Headers

Outbound webhook deliveries include these headers:
During secret rotation overlap, praeto-signature can include more than one signature:
The receiver should accept the webhook if any provided signature matches an active secret.

Verification rules

A receiver should verify:
  1. Required headers exist.
  2. Timestamp is within tolerance.
  3. Signature matches the raw request body.
  4. Event ID has not already been processed if the receiver needs idempotent processing.
Recommended timestamp tolerance:
This prevents old signed requests from being replayed much later.

Signature base string

The expected signature base string is:
Example:
The signature is:
Encoded as lowercase hex and prefixed with v1=.

Important: use the raw request body

Do not parse JSON and re-serialize it before checking the signature. This is wrong:
This is correct:
JSON serializers may change whitespace, key order, or escaping, which will break HMAC verification.

Node.js verification example

See ../examples/node/verify-praeto-signature.js. Minimal example:

Python verification example

See ../examples/python/verify_praeto_signature.py. Minimal example:

Secret rotation behavior

When an endpoint secret is rotated:
  1. The old secret becomes previous_secret.
  2. A new current secret is generated.
  3. For the configured overlap window, outbound deliveries include signatures for both current and previous secrets.
  4. After the overlap expires, only the current secret is valid.
Default overlap:
This prevents customer downtime during secret rotation.

Receiver idempotency recommendation

Praeto Dispatcher prevents duplicate event ingestion on the publisher side when Idempotency-Key is used. Receivers should still process inbound webhooks idempotently by storing:
or:
Use praeto-delivery-id if you want to dedupe exact delivery attempts. Use praeto-event-id if you want to process a business event only once regardless of replay.