SidClaw

Webhook Endpoints

Configure webhook endpoints to receive real-time notifications when approvals, traces, and agent lifecycle events occur.

Webhook Endpoints

Webhooks allow you to receive real-time HTTP callbacks when events occur in your SidClaw tenant. You register HTTPS endpoint URLs and subscribe them to specific event types. SidClaw sends a signed POST request to your URL for each matching event.

All webhook management endpoints require admin access.

Endpoint Summary

MethodPathDescriptionAuth
POST/api/v1/webhooksCreate a webhook endpointAdmin
GET/api/v1/webhooksList webhook endpointsAdmin
GET/api/v1/webhooks/:idGet webhook detailAdmin
PATCH/api/v1/webhooks/:idUpdate a webhook endpointAdmin
DELETE/api/v1/webhooks/:idDelete a webhook endpointAdmin
GET/api/v1/webhooks/:id/deliveriesGet delivery historyAdmin
POST/api/v1/webhooks/:id/testSend a test eventAdmin

Webhook Event Types

Event TypeDescription
approval.requestedA new approval request was created
approval.approvedAn approval request was approved
approval.deniedAn approval request was denied
approval.expiredAn approval request expired without a decision
trace.completedA trace was finalized (outcome recorded)
agent.suspendedAn agent was suspended
agent.revokedAn agent was revoked
policy.updatedA policy rule was updated

Webhook Payload Format

Every webhook delivery sends a JSON POST request with these headers:

HeaderDescription
Content-Typeapplication/json
X-Webhook-IDUnique delivery UUID
X-Webhook-TimestampISO 8601 timestamp of the delivery
X-Webhook-SignatureHMAC-SHA256 signature: sha256={hex_digest}

Signature Verification

The signature is computed as:

HMAC-SHA256(webhook_secret, request_body)

Verify the signature by computing the HMAC of the raw request body using the webhook secret (returned only at creation time) and comparing it to the X-Webhook-Signature header value (after stripping the sha256= prefix).

const crypto = require('crypto');

function verifySignature(body, secret, signature) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

POST /api/v1/webhooks

Create a new webhook endpoint.

Auth: API key with admin scope, or session with admin role.

Request Body

FieldTypeRequiredDescription
urlstringYesHTTPS URL to receive events (or http://localhost in development)
eventsstring[]YesArray of event types to subscribe to (at least one)
descriptionstringNoHuman-readable description

Response

Status: 201 Created

{
  "data": {
    "id": "wh-001",
    "url": "https://example.com/webhooks/sidclaw",
    "events": ["approval.requested", "approval.approved", "approval.denied"],
    "secret": "a1b2c3d4e5f6...64_hex_chars",
    "is_active": true,
    "description": "Approval notifications",
    "created_at": "2026-03-21T10:00:00.000Z"
  }
}

The secret field is only returned in the creation response. Store it securely -- it cannot be retrieved again.

Example

curl -X POST http://localhost:4000/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/sidclaw",
    "events": ["approval.requested", "approval.approved", "approval.denied"],
    "description": "Approval notifications for Slack integration"
  }'

Error Codes

StatusErrorDescription
400validation_errorInvalid URL, missing events, or invalid event types
403forbiddenAdmin role/scope required

GET /api/v1/webhooks

List all webhook endpoints for the current tenant.

Auth: API key with admin scope, or session with admin role.

Response

Status: 200 OK

{
  "data": [
    {
      "id": "wh-001",
      "url": "https://example.com/webhooks/sidclaw",
      "events": ["approval.requested", "approval.approved"],
      "is_active": true,
      "description": "Approval notifications",
      "created_at": "2026-03-21T10:00:00.000Z"
    }
  ]
}

The secret is never included in list responses.

Example

curl http://localhost:4000/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_abc123"

GET /api/v1/webhooks/:id

Get a single webhook endpoint. Does not include the secret.

Auth: API key with admin scope, or session with admin role.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint UUID

Response

Status: 200 OK

{
  "data": {
    "id": "wh-001",
    "url": "https://example.com/webhooks/sidclaw",
    "events": ["approval.requested", "approval.approved"],
    "is_active": true,
    "description": "Approval notifications",
    "created_at": "2026-03-21T10:00:00.000Z"
  }
}

Error Codes

StatusErrorDescription
404not_foundWebhook endpoint does not exist

PATCH /api/v1/webhooks/:id

Update a webhook endpoint. Only provided fields are updated.

Auth: API key with admin scope, or session with admin role.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint UUID

Request Body

All fields are optional.

FieldTypeDescription
urlstringUpdated HTTPS URL
eventsstring[]Updated event subscriptions (at least one)
is_activebooleanEnable or disable the endpoint
descriptionstring | nullUpdated description

Response

Status: 200 OK

{
  "data": {
    "id": "wh-001",
    "url": "https://example.com/webhooks/sidclaw-v2",
    "events": ["approval.requested"],
    "is_active": true,
    "description": "Updated description",
    "created_at": "2026-03-21T10:00:00.000Z"
  }
}

Example

curl -X PATCH http://localhost:4000/api/v1/webhooks/wh-001 \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["approval.requested", "trace.completed"],
    "description": "Updated to include trace events"
  }'

Error Codes

StatusErrorDescription
400validation_errorInvalid URL or event types
404not_foundWebhook endpoint does not exist

DELETE /api/v1/webhooks/:id

Delete a webhook endpoint and all its delivery history.

Auth: API key with admin scope, or session with admin role.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint UUID

Response

Status: 204 No Content

Example

curl -X DELETE http://localhost:4000/api/v1/webhooks/wh-001 \
  -H "Authorization: Bearer sk_live_abc123"

Error Codes

StatusErrorDescription
404not_foundWebhook endpoint does not exist

GET /api/v1/webhooks/:id/deliveries

Get the delivery history for a webhook endpoint. Shows each delivery attempt with its status, HTTP response code, and timing.

Auth: API key with admin scope, or session with admin role.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint UUID

Query Parameters

ParameterTypeDescription
statusstringFilter by delivery status
limitintegerItems to return (default: 20, max: 100)

Response

Status: 200 OK

{
  "data": [
    {
      "id": "del-001",
      "event_type": "approval.requested",
      "status": "delivered",
      "http_status": 200,
      "attempts": 1,
      "created_at": "2026-03-21T10:00:00.000Z",
      "delivered_at": "2026-03-21T10:00:01.000Z",
      "next_retry_at": null
    },
    {
      "id": "del-002",
      "event_type": "approval.approved",
      "status": "failed",
      "http_status": 500,
      "attempts": 3,
      "created_at": "2026-03-21T10:15:00.000Z",
      "delivered_at": null,
      "next_retry_at": "2026-03-21T11:15:00.000Z"
    }
  ]
}

Delivery Fields

FieldTypeDescription
idstringDelivery UUID
event_typestringThe event type that triggered this delivery
statusstringDelivery status (pending, delivered, failed)
http_statusnumber | nullHTTP response status from your endpoint
attemptsnumberNumber of delivery attempts
created_atstringWhen the delivery was created
delivered_atstring | nullWhen the delivery succeeded
next_retry_atstring | nullWhen the next retry is scheduled

Example

curl "http://localhost:4000/api/v1/webhooks/wh-001/deliveries?limit=50" \
  -H "Authorization: Bearer sk_live_abc123"

Error Codes

StatusErrorDescription
404not_foundWebhook endpoint does not exist

POST /api/v1/webhooks/:id/test

Send a test event to a webhook endpoint. Useful for verifying connectivity and signature validation.

Auth: API key with admin scope, or session with admin role.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint UUID

Response

Status: 200 OK

{
  "delivered": true,
  "http_status": 200,
  "response_time_ms": 142
}

If the delivery fails:

{
  "delivered": false,
  "http_status": null,
  "response_time_ms": 10023,
  "error": "AbortError: The operation was aborted"
}

The test event payload has this shape:

{
  "id": "test-uuid",
  "event": "test",
  "timestamp": "2026-03-21T10:00:00.000Z",
  "tenant_id": "your-tenant-id",
  "data": {
    "message": "Test webhook from Agent Identity"
  }
}

The request times out after 10 seconds.

Example

curl -X POST http://localhost:4000/api/v1/webhooks/wh-001/test \
  -H "Authorization: Bearer sk_live_abc123"

Error Codes

StatusErrorDescription
404not_foundWebhook endpoint does not exist