How signing works
Each delivery includes anX-Hopae-Signature header with two comma-separated fields:
The signed payload is constructed as:
<raw-request-body> is the exact UTF-8 bytes of the JSON body received in the HTTP request.
Verifying the signature
End-to-end Express example
Useexpress.raw() middleware on the webhook route so the handler receives the untouched body. Express’s default JSON parser destroys the exact bytes the signature was computed over.
Event types
Choose the event types in your app’s webhook settings in the Console. Each delivery includes the event type in theevent field of the payload.
Each payload has the shape:
event is a string; the nested data.event is an object with its own type, timestamp, and optional metadata — they carry the same event type value, but data.event.metadata lets you pass extra context through the delivery pipeline.
Obtaining your webhook secret
Generate the webhook secret in the Console, in your app’s webhook settings. Store the secret securely (e.g. as an environment variable).Replay protection
Thet timestamp in the signature header reflects the moment the delivery was sent. Hopae recommends rejecting webhooks where |now - t| > 300 seconds (5 minutes) to prevent replay attacks, as shown in the examples above.
Backwards compatibility
Apps without a webhook secret deliver webhooks without anX-Hopae-Signature header. Generate the secret once in the Console to enable signing on your app.
