Webhooks

Real-time governance event delivery.

8 event types. HMAC-SHA256 signature verification. Events delivered within 5 seconds of log admission.

8 event typesHMAC-SHA256

Event types

EventWhen it firesPayload typeUse case
leaf_admitted Governance Envelope admitted to log AGTS_GOVERNANCE_ENVELOPE_V1 Trigger downstream workflows on successful governance
gate_fail One or more gates rejected evidence Gate failure summary with gates_failed Trigger alert, block deployment, escalate to review
compliance_report_ready Compliance report generated for a proof bundle AGTS_COMPLIANCE_REPORT_V1 Notify compliance officer; push to document management system
execution_trace_admitted Execution trace leaf admitted (L2+) AGTS_EXECUTION_TRACE_V1 Begin variance computation; update monitoring dashboard
variance_recorded Variance record leaf admitted (L2+) AGTS_VARIANCE_RECORD_V1 Update risk dashboard; compare against thresholds
governance_breach Variance record with classification: "BREACH" or omega_breach: true Variance record + auth context Immediate alert: governance gap detected — execution exceeded authorized bounds
chain_depth_milestone Governance chain depth hits a milestone (10 / 100 / 1000 leaves) Chain depth summary Progress notification; update compliance dashboard
observables_alert HCE observables cross a policy threshold Observable summary + threshold crossed Risk alert: system health or coherence degrading — review governance posture

Registering a webhook

curl -X POST https://api.obligationsign.com/webhooks \ -H "Authorization: Bearer agts_live_..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-system.example.com/governance-hook", "events": ["leaf_admitted", "gate_fail", "governance_breach"], "secret": "optional-signing-secret-you-generate" }' # Response: { "webhook_id": "wh_a7f3c2...", "url": "https://your-system.example.com/governance-hook", "events": ["leaf_admitted", "gate_fail", "governance_breach"], "created_at": "2026-03-14T14:00:00Z" }

Signature verification

Every delivery includes an X-AGTS-Signature-256 header. Verify it before processing:

// Node.js / Express const crypto = require('crypto'); function verifyWebhook(req, secret) { const signature = req.headers['x-agts-signature-256']; if (!signature) return false; const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(req.rawBody) // must be raw bytes, not parsed JSON .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } app.post('/governance-hook', (req, res) => { if (!verifyWebhook(req, process.env.WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } const event = req.body; // handle event.type: switch (event.type) { case 'leaf_admitted': console.log('Leaf admitted:', event.leaf_hash); break; case 'governance_breach': alertOnCall(event.payload); break; case 'gate_fail': blockDeployment(event.payload.gates_failed); break; } res.sendStatus(200); });

Payload examples

leaf_admitted

{ "type": "leaf_admitted", "tenant_id": "tn_a7f3c2...", "leaf_index": 42, "leaf_hash": "8f3a1b...", "admitted_at": "2026-03-14T14:30:00Z", "subject_id": "customer-chatbot:v1.2", "replay_url": "https://obligationsign.com/replay?leaf=8f3a1b..." }

gate_fail

{ "type": "gate_fail", "tenant_id": "tn_a7f3c2...", "subject_id": "customer-chatbot:v1.3", "gates_failed": ["G1"], "details": { "G1": "confidence_interval_lower (0.62) below threshold (0.70)" }, "action": "ACTION_BLOCKED", "failed_at": "2026-03-14T14:31:00Z" }

governance_breach

{ "type": "governance_breach", "tenant_id": "tn_a7f3c2...", "auth_leaf_hash": "8f3a1b...", "exec_leaf_hash": "9c4b2d...", "variance_leaf_hash": "7a5e3f...", "classification": "BREACH", "l2_distance": 0.31, "omega_breach": true, "drift_direction": { "H": "degraded", "C": "degraded", "E": "degraded" }, "recorded_at": "2026-03-14T14:32:00Z" }

Delivery semantics

PropertyValue
Delivery latency≤ 5 seconds after log admission
Retry policyExponential backoff: 5s, 30s, 2m, 10m, 30m (5 attempts)
Timeout per attempt10 seconds
Success criteriaYour endpoint returns HTTP 200
Ordering guaranteeBest-effort in admission order; no strict ordering guarantee across event types
At-least-once deliveryYes — handle idempotency using leaf_hash or event timestamp
Maximum payload size128 KB
API reference → Get started →