Webhooks
The push-side of the platform. Substrate events fan out to your endpoint under the same identity, tier, and audit-chain semantics as every other operation — the delivery itself is a chain entry.
Event topics
| Topic prefix | Fires when | Payload includes |
|---|---|---|
task.* | Task lifecycle — created, assigned, status_changed, decomposed, closed | Operator identity, audit-chain entry id |
signal.* | Orchestrator signals — raised, acknowledged, escalated, resolved | Department, severity, delegator on acknowledgements |
pearl.* | Pearl-level — trained, retrained, memory_registered, insight_produced | Scoped to the department the Pearl serves |
audit.* | Audit-chain — entry_written, verification_run, receipt_issued | Chain entry ids, receipt signatures |
identity.* | Identity plane — token_issued, cradle_attested, tier_escalated, delegation_granted | The events a security operations centre subscribes to |
Delivery semantics
Every subscription targets one URL. The platform delivers each event at least once; deliveries are idempotent by event_id. Your endpoint should be able to accept a duplicate delivery without side-effects — the platform retries on any non-2xx response.
Order is preserved within a topic-and-target pair on a best-effort basis; if your handler must see events in strict order, use the sequence field on the payload to sort locally rather than relying on delivery order.
The retry envelope
Failed deliveries retry on an exponential backoff:
30s → 2m → 10m → 1h → 6h → 24hA subscription that has failed six consecutive deliveries goes into a quarantined state — new events are queued but not sent, and the platform emails the subscription owner. Restoring the endpoint and calling webhooks/resume replays the queued backlog in order.
Quarantine protects the platform’s outbound queue from a silently-broken customer endpoint. It is not a limit on how many deliveries the platform will ever attempt — once resumed, every queued event delivers.
Signature verification
Every delivery carries an X-Nebbos-Signature header: an HMAC-SHA-256 of the request body, keyed with a subscription-level secret. Verify the signature in constant time before trusting a single byte of the payload.
Python
import hmac, hashlib
def verify(body: bytes, header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)The platform never uses a shared secret across subscriptions — each has its own key, rotatable on demand.
Every delivery is an audit entry
Both the outbound delivery (which event, to what URL, at what time) and the receiver’s response (status code, duration) land in the audit chain. A quarantine event, a resumed backlog, a signature failure — all visible from the same chain read.