Documentation Index
Fetch the complete documentation index at: https://docs.getzenstep.com/llms.txt
Use this file to discover all available pages before exploring further.
Signature verification
Every webhook request from Zenstep includes anX-Zenstep-Signature header containing an HMAC-SHA256 signature of the raw request body. You should verify this signature before processing any webhook payload.
Getting your webhook secret
When you create a webhook endpoint in the dashboard (Settings → Notifications → Add webhook), Zenstep generates a unique secret for that endpoint. Copy the secret immediately — it is only shown once. If you lose the secret, rotate it from the webhook settings page. All subsequent deliveries will use the new secret.Verifying the signature
Security best practices
Always verify signatures — do not process webhook payloads without signature verification, even in development. Use the raw request body — compute the HMAC over the raw bytes of the request body before JSON parsing. Whitespace differences will cause signature mismatches. Use timing-safe comparison — always usecrypto.timingSafeEqual (Node.js), hmac.compare_digest (Python), or hmac.Equal (Go) to compare the computed and received signatures. Standard string comparison is vulnerable to timing attacks.
Store the secret in an environment variable — never hardcode the webhook secret in your source code.
Reject requests without the header — if X-Zenstep-Signature is missing, return 401 immediately.
Replay attacks
To prevent replay attacks, Zenstep includes atimestamp field in every payload. Reject payloads where the timestamp is more than 5 minutes in the past:
id field. If your application requires strict idempotency, store processed delivery IDs and skip re-processing.