Webhooks.
Outbound delivery for things you should not have to poll for, with retries and a dispatcher you can see the state of.
What they are for
Pulling a TAXII collection on a timer is right for bulk intel. It is wrong for “tell me the moment an advisory that affects me is published”. Webhooks cover the second case.
Delivery
A pending event is written to the database first, then a dedicated webhook-dispatcher worker POSTs it to your endpoint. Because the event is persisted before the attempt, a dispatcher restart does not lose events.
- Retries use exponential backoff rather than a fixed interval.
- Attempt count and last error are recorded per delivery.
- Delivery is at-least-once — your handler should be idempotent.
Advisory channels
Advisories fan out over up to three channels per subscribed tenant: portal (an in-app notification, delivered immediately), email, and webhook. Each is recorded as its own delivery row so partial success is visible.
The portal channel is written synchronously when an advisory is sent, so an in-app notification appears at once. email and webhook rows are left pending for the dispatcher. If that worker is not running, those two channels stay pending indefinitely and the advisory looks sent from the portal's point of view.
Subscriptions
Managed under /v1/webhooks. A tenant chooses which channels it wants and a minimum severity, so a subscription can be scoped to “only critical” without filtering on your side.