Skip to main content
Every webhook request from Yoshi is signed with HMAC-SHA256 so you can verify it came from Yoshi and hasn’t been tampered with. Always verify signatures before processing events.

Quick start

The fastest way to verify webhooks is with the SDK:

How signing works

Every webhook request includes two headers: The signature is computed as:
Where secret is your webhook signing secret (starts with whsec_), timestamp is the value of the x-yoshi-timestamp header, and raw_body is the raw request body string.
You must use the raw request body for verification, not a parsed-then-serialized version. Most frameworks parse JSON automatically — make sure you capture the raw body before parsing.

Framework examples

Replay protection

The SDK rejects webhooks with timestamps older than 5 minutes by default. This prevents replay attacks where an attacker resends a captured webhook request. You can customize this tolerance:

Manual verification

If you prefer to verify signatures without the SDK:
Always use constant-time comparison (timingSafeEqual in Node.js, hmac.compare_digest in Python, hmac.Equal in Go) to prevent timing attacks. Never use === or == for signature comparison.

Secret rotation

When you rotate your signing secret, there is a brief window where both the old and new secrets are valid. During this window, Yoshi signs webhooks with both secrets. Your verification logic should try the new secret first, then fall back to the old secret. The SDK handles this automatically if you pass an array of secrets:
Last modified on April 17, 2026