Skip to main content
Every webhook GlobalStack sends is signed. Verify the signature on each delivery before you act on it β€” it proves the request came from GlobalStack and the body was not altered in transit. Signatures follow the Svix standard, so you can verify them with an official Svix library in one call, or implement the check yourself.

What’s on each delivery

Every request carries three headers: Your signing secret (prefixed whsec_) is shown in plaintext once β€” when you create a webhook endpoint or rotate its secret. Store it securely; you cannot retrieve it again.
Verify against the raw request body β€” the exact bytes you received. If you parse the JSON and re-serialize it before verifying, the bytes change and verification fails. Read the raw body first, verify, then parse.
The library handles the construction, the multi-signature format, timing-safe comparison, and timestamp (replay) checks for you.
Svix maintains official verification libraries for these and more languages. Install with your package manager β€” npm i svix, pip install svix, go get github.com/svix/svix-webhooks/go, gem install svix, composer require svix/svix, or Maven/Gradle (com.svix:svix) β€” and see the full list.

Verify manually

If there’s no Svix library for your stack, reproduce the signature yourself:
1

Build the signed content

Join the id, timestamp, and the raw body with dots: signed_content = svix_id + "." + svix_timestamp + "." + raw_body
2

Derive the key

Drop the whsec_ prefix from your signing secret and base64-decode the remainder. Those bytes are your HMAC key.
3

Sign

Compute base64(HMAC-SHA256(key, signed_content)).
4

Compare

The svix-signature header is a space-separated list of v1,<signature> entries (an endpoint can have more than one valid secret during a rotation). Compare your value against each entry’s signature β€” the part after v1, β€” using a constant-time comparison. Accept if any matches.
5

Check the timestamp

Reject deliveries whose svix-timestamp is more than a few minutes from your current time, to guard against replay.

Deduplicating events

The body’s event_id equals the svix-id without its msg_ prefix. Use either to deduplicate β€” a delivery may be retried, and the same event_id arrives more than once. Treat your handler as idempotent: record processed event_ids and ignore repeats.