Two surfaces, same deliveries:
- API:
https://api.aegis-kyt.com/v1/webhooks/*·X-API-Key: aeg_<48 chars>— for x402 consumers / integrations without a UI session - Dashboard:
https://app.aegis-kyt.com/webhooks— for VASP / PSP customers using the web app; scoped to your subgroup
When you’d use webhooks
| Event type | Fires when | Useful for |
|---|---|---|
tx.policy.alert.triggered | A /check-transfer or /v1/aegis/tx check raises at least one policy alert above your configured alert_min_level | KYT — funnel inbound deposits into your case-review queue |
aegis.bfs.completed | An asynchronous Tier-4 exposure job finishes | Long-running BFS pre-screening, batch flows |
aegis.bfs.failed | Same job gives up after retries | Surface the failure into your ops queue |
aegis.check.high_risk | A /v1/aegis/check returns risk_level high or severe | Real-time alerting on standalone address checks |
Delivery contract
Every delivery is aPOST to your URL with these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | aegis-webhooks/1 |
X-Aegis-Event | The event_type string, e.g. tx.policy.alert.triggered |
X-Aegis-Signature | Base64-encoded HMAC_SHA256(secret, raw_body) |
X-Aegis-Delivery-Id | UUID of this delivery attempt — survives retries (idempotency key) |
X-Aegis-Attempt | 1-based attempt counter (1 on first try, 2 on first retry, etc.) |
- Verify the signature against the raw request body (don’t parse + re-serialize — JSON whitespace matters).
- Respond
2xxwithin 15 s — anything else is retried. - Deduplicate by
X-Aegis-Delivery-Idif you store events — we retry on any non-2xx, so the same delivery_id may arrive multiple times during transient outages.
Signature verification
The signature is computed over the exact bytes of the POST body:hmac.compare_digest /
crypto.timingSafeEqual) — direct === leaks timing.
Retry policy
Delivery attempts on non-2xx response or network error:| Attempt | Delay |
|---|---|
| 1 | immediate |
| 2 | +30 s |
| 3 | +2 min |
| 4 | +10 min |
| 5 | +1 h |
gave_up. If a
subscription accumulates failure_threshold consecutive
gave_up deliveries (default 5, configurable per subscription),
we auto-disable the subscription and send a Telegram alert
to the operator channel. Re-enable via PUT /v1/webhooks/{id}
with {is_active: true} — that also resets the failure counter.
Synthetic test event
UsePOST /v1/webhooks/{sub_id}/test to send a synthetic event
through the same signature + retry plumbing real events use.
Payloads carry sentinel ids (00000000-…) and a top-level
synthetic: true field so your handler can short-circuit them
if desired. See /v1/webhooks//test.
What you don’t get
- No queueing on your side — if your endpoint is down for >1 h (sum of retry window) we give up on the individual delivery. Critical events should still be polled defensively.
- No batching — one HTTP call per event, per subscription.
- No filtering beyond event_type + your
subgroup_aml_configalert_min_level — fortx.policy.alert.triggered, see event schemas for the body fields you can route on.

