whsec_...). Anyone can POST to your URL, so verify the signature before you trust a delivery. The official standardwebhooks libraries do it in one call.
What a delivery looks like
Alura sends aPOST with a JSON body: the event exactly as GET /v1/events/{id} returns it, byte for byte.
Verify in Node
Install the library withnpm install standardwebhooks. Verify the raw body as it arrived: JSON that was parsed and written again doesn’t match its signature.
Verify in Python
Install the library withpip install standardwebhooks. With Flask:
Send a test event
POST /v1/webhooks/{id}/test sends your endpoint a webhook.test event, signed like every delivery. It has the same envelope, with shop_id set to null and data set to {"event_type": "webhook.test"}. It’s sent once, without retries, and it isn’t stored as an event, so GET /v1/events doesn’t list it. Watch the result with GET /v1/webhooks/{id}/deliveries.
Rotate the secret
POST /v1/webhooks/{id}/rotate-secret returns a new secret, once. The old secret keeps signing for 24 hours, and every delivery in that time carries a signature from each. To switch without missing a delivery:
- Rotate, and store the new secret.
- Deploy your verifier with the new secret. Deliveries verify with either secret during the 24 hours, so the order of your deploys doesn’t matter.
- After 24 hours, deliveries carry only the new signature.
Good practice
- Reject what doesn’t verify with a 4xx. Alura counts any 2xx as delivered, and anything else as a failure to retry.
- De-duplicate on
webhook-id. A retry, or an attempt sent again after an interruption on Alura’s side, carries the samewebhook-id. - Answer within 15 seconds. Alura gives up on an attempt after 15 seconds and retries it later. Queue slow work.
- Don’t allowlist IP addresses. Deliveries come from Google Cloud addresses that change. The signature is the check.
- Redirects aren’t followed. A
3xxanswer counts as a failure, so point the endpoint at its final URL.