Standard Webhooks
Skovik webhooks follow the Standard Webhooks specification. This is an open specification that defines a common shape for webhook headers, signatures and payloads, so that you can use ready-made verification libraries.
Every webhook request includes the following headers:
Content-Type: application/json
User-Agent: Skovik-Webhook (+https://developer.skovik.com)
webhook-id: <unique delivery id>
webhook-timestamp: <unix timestamp in seconds>
webhook-signature: <HMAC-SHA256 signature>The webhook-id identifies a single delivery to a given endpoint, consistent across retries of that delivery. Use it for deduplication if needed. The webhook-timestamp reflects when Skovik signed and dispatched that particular attempt. It changes between retries. The webhook-signature is an HMAC-SHA256 over the id, timestamp and body, using the endpoint's signing secret as the key.
Signing secrets are issued in the Standard Webhooks format: the prefix whsec_ followed by a base64-encoded random value.
Verifying webhooks
You must verify the signature on every incoming webhook. An unverified request cannot be trusted, because anyone who knows your endpoint URL could otherwise call it with arbitrary content. Verification confirms two things: that the request was sent by Skovik using the secret we share with you, and that the payload has not been tampered with in transit.
Libraries are available for most languages on the Standard Webhooks GitHub organization.
Keep in mind is that the signature is computed over the raw, unparsed request body. If your web framework parses the JSON automatically, the signature will likely not match. Capture the body as a string or byte buffer before any JSON parsing takes place.
Note that each endpoint has its own secret. Verify requests with the correct secret.
Delivery and retries
A delivery is successful when the destination responds with a 2xx HTTP status within 5 seconds. Any other response, including timeouts and connection errors, is treated as a failed delivery and scheduled for retry.
Retries use exponential backoff with jitter, spanning roughly three days from the initial attempt. If all retries are exhausted without success, the delivery is abandoned. An endpoint that fails for an extended period will be automatically disabled, and you will need to re-enable it from the UI. If an endpoint responds with HTTP 410 Gone, the system will stop sending events to it.
Endpoints should aim to respond quickly and do any heavy processing asynchronously. Accept the request, verify the signature, enqueue async work and return a 2xx response. Slow responses increase the risk of timeouts and retries.
Since retries can cause the same event to be delivered more than once, your endpoint should be idempotent. The webhook-id header is the same across all delivery attempts and is a convenient deduplication key.
