Credentials
The webhook URL and signing secret are displayed once in the Webhook dialog when the trigger is created or its secret is regenerated.Request
Send an HTTPPOST request to the webhook URL.
Signing procedure
Follow these steps to generate a signature for each webhook request.- Serialize the request body: Convert the JSON body into a string and retain the exact bytes.
- Generate the timestamp: Get the current Unix timestamp in seconds (
ts). - Construct the signed message: Combine the timestamp, a period (
.), and the raw request body. - Generate the HMAC: Compute HMAC-SHA256 using the signed message and the complete signing secret, including the
whsec_prefix, as the UTF-8 key. - Format the signature: Convert the HMAC digest into lowercase hexadecimal.
- Send the request: Include the timestamp and signature in the request headers. Ensure the request body contains the exact bytes used to generate the signature.
Worked example
The following example illustrates how the signed message and signature are constructed.Rules
Follow these requirements when signing and sending webhook requests.- Request body: Send the exact bytes used to generate the signature. Re-serializing the JSON body, including changing the key order, spacing, or formatting, returns
401 invalid_signature. - Signing secret: Use the complete signing secret, including the
whsec_prefix, as the HMAC key. Removing the prefix or Base64-decoding the secret returns401 invalid_signature. - Timestamp validity: The timestamp must be within 300 seconds (5 minutes) of the server’s current time. Timestamps outside this window, including those caused by clock differences, return
401 stale_timestamp. - Timestamp format: Send the timestamp as a plain integer in seconds. Milliseconds, leading zeros, or decimal values return
401 stale_timestamp. - Content type: Set
Content-Typetoapplication/json. Other content types leave the request body unread and cause signature validation to fail. - Retries: Generate a fresh timestamp and signature for every retry. Requests replayed after 300 seconds are rejected.
- Secret security: Do not expose the signing secret in client-side code or application logs. Anyone with the secret can initiate agent runs.
- Duplicate requests: Accepted requests are not automatically deduplicated. Each accepted request starts a new agent run.
- Secret regeneration: Update callers immediately after regenerating the signing secret. The previous secret becomes invalid at once.