Webhook Headers & Verification
Every webhook delivery is an HTTP POST with a JSON body and three relevant headers.HTTP headers
Example:
Get the public key
UseGET /v1/webhooks-keys to list public keys. Use the key with is_active: true.
Cache the key for up to 24 hours and refresh periodically.
Verification process
Step 1: Validate timestamp
Reject deliveries with timestamps outside a 5-minute window from current time (replay protection).Step 2: Reconstruct the signed message
PoP format (same pattern as API authentication, with a differenturi component):
Step 3: Verify the signature
- Compute SHA-256 of the UTF-8 message bytes
- Decode
x-kiwify-digital-signaturefrom base64url (no padding) - Verify with EdDSA-Ed25519 using the active public key
Example (Python)
Common mistakes
- Using the full URL instead of only the path in the signed message
- Re-serializing JSON (whitespace/key order changes the signature)
- Verifying Ed25519 directly on the message without SHA-256 prehash
