Webhooks support HMAC signing (
X-Decimal-Signature) for verifiable delivery and automatic retry with backoff on failure. Set a webhook secret and verify signatures so you can trust the payload. Delivery is still subject to a 5-second per-attempt timeout — acknowledge fast and process asynchronously.Setup
In Settings → Notifications, set:- Webhook URL — the HTTPS endpoint that receives events.
- Enabled events — which event types to send. Defaults to all events.
Event types
| Event | Fires when |
|---|---|
manifest.changed | A new manifest version is registered for an agent (new tools, prompt sections, model, or skill set). |
regression.detected | The post-deploy bisect view marks a manifest version as a regression. |
regression.resolved | A previously-flagged regression is marked resolved (rollback or fix shipped). |
usage.warning | Your org has consumed 80% of a plan limit (traces ingested, SFT rows). |
usage.limit_reached | Your org has consumed 100% of a plan limit. Further requests return 402. |
payment.failed | Stripe reports a failed payment. Grace period starts; service degrades after the grace window. |
payment.confirmed | Stripe confirms a successful payment. |
Payload format
Every webhook body has the same envelope. Thedata field carries event-specific fields.
data field for each event:
manifest.changed
manifest.changed
regression.detected / regression.resolved
regression.detected / regression.resolved
usage.warning / usage.limit_reached
usage.warning / usage.limit_reached
payment.failed / payment.confirmed
payment.failed / payment.confirmed
Headers
Every webhook request includes:| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | DecimalAI-Webhooks/1.0 |
X-Decimal-Event | The event name (e.g., regression.detected) |
X-Decimal-Event-Id | Unique ID for this delivery — use it to deduplicate retries. |
X-Decimal-Signature | sha256=<hex> HMAC over the raw body, present when a webhook secret is configured. See Verifying webhooks. |
Verifying webhooks
When your org has a webhook secret configured, every webhook request carries anX-Decimal-Signature header of the form sha256=<hex_digest> — an HMAC-SHA256 over the raw request body bytes using your secret. Verify it before trusting the payload. Set or rotate the secret in Settings → Notifications.
The signature covers the exact bytes DecimalAI sent. Verify against
await request.body() (or your framework’s raw-body accessor) — re-serializing the parsed JSON can reorder keys and break the comparison.Receiving — example handlers
Retries and delivery
Each delivery attempt has a 5-second timeout. If your endpoint returns a non-2xx response or times out, the dispatch is recorded as failed and automatically retried — a background scheduler replays failed dispatches with backoff (and jitter), up to a few attempts, before giving up. Because retries can redeliver the same event, treat your handler as idempotent: deduplicate on theX-Decimal-Event-Id header so a replayed delivery is a no-op.
If your webhook handler is slow or unreliable, return 200 immediately and process asynchronously. Anything longer than 5 seconds counts as a failed attempt and will be retried.
Disabling webhooks
Either:- Remove the webhook URL in Settings → Notifications, or
- Set
webhook_urltonullvia the API.
Next Steps
Errors
HTTP status codes and how to handle them.
Roadmap
What’s shipped (HMAC signing, retry) and what’s still in flight.