Skip to main content

Signature Verification

Hop signs every webhook delivery using HMAC-SHA256. The signing input is the timestamp, a period, and the exact raw request body:
The result is sent in the X-Webhook-Signature header:
The signed bytes are the exact compact JSON Hop transmits. No spaces between keys and values, and keys in the order Hop emits them. Verify against the raw request body your framework received. Parsing the JSON and re-serializing it produces different bytes and a signature that will never match, so capture the body before any middleware decodes it. Both examples reject deliveries whose X-Webhook-Timestamp is more than 300 seconds from the current time.

Python

JavaScript

Endpoint Requirements

  • HTTPS only: a URL that is not https with a host is rejected at creation with 422 VALIDATION_ERROR, and the same check runs on update.
  • Respond within 10 seconds: each delivery attempt has a 10-second HTTP timeout. Return a 2xx quickly and process the event asynchronously.
  • Return 2xx: connection errors, timeouts, and non-2xx responses trigger a retry.
  • Keep the secret private: it is returned only when the webhook endpoint is created, and it is the only thing standing between your handler and a forged delivery.

Testing Signatures

Use a timestamp and raw payload when testing the signing calculation: