Subscribing to Events via Webhooks
A Webhook is a way to send information or notifications from one application to another when a specific event occurs, using an HTTP POST request.
AltScore allows you to subscribe to events occurring on the platform via Webhooks. Delivery is handled by Svix, which gives you a cryptographic signature on every send, automatic retries and, above all, visibility: you can now see whether an event reached your endpoint and retry it if it failed.
Configuring your webhooks from the hub
The recommended way to manage webhooks is from the AltScore hub, under Settings > Webhooks. There you will find the webhooks portal, where you can:
- Register an endpoint and choose which events it subscribes to.
- See the delivery history for each endpoint, with every attempt, your server's response and the payload that was sent.
- Manually retry any message that failed, without having to ask support.
- Look up each endpoint's signing secret, which you need in order to verify deliveries.
- Send test messages to your endpoint while you build it.
The delivery history is the most useful addition: previously there was no way to tell whether a notification had arrived. If you suspect you missed an event, check here before escalating.
Verifying the signature
Always verify the signature before processing the request body. Without this, anyone who knows your endpoint URL can send you a forged POST and your system will treat it as a legitimate AltScore event.
Every delivery includes three headers:
| Header | Content |
|---|---|
svix-id | Unique identifier of the message |
svix-timestamp | Time of the attempt, in seconds since epoch |
svix-signature | Space-delimited list of signatures, each prefixed with v1, |
The signing secret is specific to each endpoint and you get it from Settings > Webhooks. It starts with the whsec_
prefix.
Using the Svix libraries
This is the recommended approach: beyond checking the signature, these libraries automatically reject messages whose
svix-timestamp is more than five minutes away from the current time, in the past or the future, which protects you
against replay attacks.
The signature is computed over the exact body you receive. Your framework must not parse, reformat or reserialize the
JSON before verification: pass verify the raw body, exactly as it arrived. Any change, however small, invalidates
the signature.
Verifying manually
If you would rather not add a dependency, the procedure is:
- Build the signed content by concatenating
{svix-id}.{svix-timestamp}.{body}. - Base64-decode the portion of the secret that follows
whsec_. - Compute an HMAC with SHA-256 over the signed content using that secret, and base64-encode the result.
- Compare that result against each signature in
svix-signature, first stripping the version prefix (v1,). The header may carry several space-delimited signatures; a match on any one of them is enough. - Check that
svix-timestampis within your tolerance of your server's clock, to rule out replays.
Use a constant-time comparison (for example hmac.compare_digest in Python) to prevent timing attacks. If you verify
manually, your server needs its clock synchronized via NTP.
Retries and delivery
If your endpoint does not respond, Svix retries automatically with increasing backoff. The attempt schedule is:
- Immediately
- 5 seconds
- 5 minutes
- 30 minutes
- 2 hours
- 5 hours
- 10 hours
- 10 hours (in addition to the previous)
A delivery counts as successful when your endpoint responds with a 2xx status code within 15 seconds. Any other
response, including redirects, counts as a failure. Once the attempts are exhausted, the message is marked as failed and
you can retry it by hand from Settings > Webhooks.
If every delivery to an endpoint fails for 5 consecutive days, the endpoint is disabled automatically.
Your endpoint must be idempotent. A retry can duplicate an event you actually did process, for example if you replied
late, so use the message's svix-id as the key to discard duplicates.
Respond quickly: accept the event, queue it and process it afterwards. If you do the heavy work before responding, you may exceed 15 seconds and trigger retries of an event you already processed.
Managing webhooks via API
Everything available in the hub has an API equivalent, documented in Webhooks API. The structure of the event you receive is described in Events.
The previous API (/v1/webhooks/:partnerId on api.altscore.ai) has been replaced. The Python SDK's comms.webhooks
module still points at that API and does not manage the new endpoints: use the hub or the HTTP API until the SDK is
updated.