Skip to main content
Every request Base44 sends is signed with your workspace’s private Ed25519 key. Verify the signature before you trust a request, so a forged or replayed call is rejected.

Signature headers

Each request carries 3 headers, following the Standard Webhooks specification. During a key rotation, webhook-signature carries 2 signatures, one per key. A request is valid when any one of them verifies.

Getting your public keys

Your workspace’s public keys are published at a URL anyone can read. Public keys can’t sign anything, so they’re safe to share.
The fields are described in Get the public key set.
A public_key is whpk_ followed by the standard base64 (not base64url) of the 32 raw key bytes. The signature header carries no key ID, so try each key in the list. Keys come newest first, a page at a time. When next_cursor isn’t null, request the next page with ?cursor=<next_cursor> until it is, and keep every key. A workspace holds one key, or two during a rotation, so the first page is usually the whole set.
Caching the keys:
  • The response can be cached for 5 minutes. Refresh it once when no key verifies a request, before you reject it.
  • You can also copy the key from See public keys on your workspace’s webhooks settings page and store it in your receiver. If you do, add the new key during a rotation.

Verifying a signature

Verification takes 3 checks, all on the raw request body, before you parse any JSON:
  1. Check the timestamp. Reject a request whose webhook-timestamp is more than 5 minutes from your clock. This stops an old request from being replayed.
  2. Build the signed content. Join webhook-id, webhook-timestamp and the raw body with a . between each: {webhook-id}.{webhook-timestamp}.{raw body}.
  3. Verify. For each v1a entry in webhook-signature, verify its signature over the signed content with each of your public keys. Accept the request if any pair matches.
Verify the exact bytes you received. Parsing the JSON and serializing it again changes the bytes, and the signature no longer matches.
Each example below is complete, needs no library beyond the standard one (or cryptography for Python), and returns true only for a genuine request.

When the key changes

A workspace admin can rotate or revoke the signing key from See public keys. Your receiver keeps working through both if it reads the key URL above, or if you add the new key in time.
  • Rotation: Base44 signs with both the old and the new key for 24 hours, and both appear in the key URL. If you store the key in your receiver, add the new one before the overlap ends. An admin can end the overlap early with Finish rotation.
  • Revocation: Base44 stops signing with the revoked key on the next request. A receiver that reads the key URL picks up the replacement within 5 minutes. A receiver that stores only the revoked key rejects deliveries until you give it the new one, and those deliveries retry meanwhile.