@contextgraph/webhooks

Webhook management with delivery queue and retry logic.

Installation

pnpm add @contextgraph/webhooks

Overview

Send HTTP callbacks for system events:

  • Webhook registration
  • Event filtering
  • Delivery queue
  • Retry with backoff

Registering Webhooks

import { WebhookManager } from '@contextgraph/webhooks';

const webhooks = new WebhookManager(storage);
await webhooks.initialize();

await webhooks.register({
  url: 'https://example.com/webhook',
  events: ['entity:created', 'decision:approved'],
  secret: 'webhook-secret',
  headers: {
    'X-Custom-Header': 'value',
  },
});

Supported Events

EventDescription
entity:createdNew entity created
entity:updatedEntity updated
claim:addedClaim added
claim:revokedClaim revoked
decision:proposedDecision recorded
decision:approvedDecision approved
decision:rejectedDecision rejected
execution:completedAction executed
policy:createdPolicy created

Webhook Payload

{
  "event": "entity:created",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "id": "ent_abc123",
    "type": "person",
    "name": "Alice"
  }
}

Signature Verification

Webhooks include HMAC signature:

X-Webhook-Signature: sha256=abc123...

Verify in your handler:

import crypto from 'crypto';

function verifySignature(payload: string, signature: string, secret: string) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return `sha256=${expected}` === signature;
}

Retry Policy

Failed deliveries are retried:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours

Managing Webhooks

// List webhooks
const hooks = await webhooks.list();

// Disable webhook
await webhooks.disable(webhookId);

// Enable webhook
await webhooks.enable(webhookId);

// Delete webhook
await webhooks.delete(webhookId);

// Get delivery history
const history = await webhooks.getDeliveries(webhookId, { limit: 50 });