Skip to main content
This page explains how the Manuscript API signs the webhook deliveries it sends you, and how to verify them. It is for anyone building the endpoint that receives them. The rules below are the Manuscript API’s own, taken from its OpenAPI document. composerID’s reference verifier, adapter/webhook_verify.py, implements them exactly, and composerID signs its own outbound webhooks the same way. When your system receives webhook events, for example document or assessment updates, your endpoint will receive HTTP POST requests from our platform. These requests are signed using your configured signing keys. You should verify the signature to ensure that:
  • The request was sent by us, and
  • The payload has not been modified in transit.

Signature headers

Webhook requests may include one or more signature headers. A separate signature header is included for each active signing key. During key rotation, this means a request may contain multiple signatures. Example:
Signature headers
Each header value is the Base64 encoded HMAC-SHA256 digest of the raw request body, generated using one of the active signing keys. The numeric suffix (-1, -2, etc.) is an identifier only. It does not map to a specific signing key and should not be relied upon.

How to validate the request

To verify a webhook request:
  1. Read the raw request body exactly as received.
  2. Compute an HMAC-SHA256 digest using each of your active signing keys.
  3. Base64 encode each digest.
  4. Compare each computed digest against all X-Signature-HMAC-SHA256-* header values.
  5. Treat the request as valid if any computed digest matches any header value.
  6. Reject the request if no signatures match.

Important implementation notes

  • Use the raw request body, not a parsed or re-serialised JSON payload.
  • Do not modify the request body before computing the signature.
  • Signature values are Base64 encoded and may include padding (=).
  • More than one signature header may be sent when multiple signing keys are active.
  • Do not assume any relationship between the header suffix and a specific signing key.
  • Compare the computed and supplied signatures using a secure comparison method.
  • Reject requests where no valid signature is present.

Key rotation

To support key rotation, multiple signing keys can be active at the same time. When this happens:
  • webhook requests will include multiple signature headers,
  • each signature is generated using a different active key,
  • your application should validate the request against all active keys and all supplied headers.
A request should be accepted if any one valid match is found.

Examples

The following example demonstrates how to validate a single signature. If multiple signing keys or signature headers are present, repeat this process and accept the request if any signature matches.