Subscribe

POST /api/v1/orgs/{slug}/webhooks
webhooks:write
curl -X POST https://api.boxowl.me/api/v1/orgs/acme/webhooks \
  -H "X-API-Key: boxlive_01h455..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.acme.com/webhooks/boxowl",
    "events": ["consent.granted", "consent.revoked", "vault.updated"],
    "description": "Production vault event handler"
  }'

Response 201 Created:

{
  "webhookId": "wh_01h455vb4pex5vsknk084sn02q",
  "url": "https://api.acme.com/webhooks/boxowl",
  "events": ["consent.granted", "consent.revoked", "vault.updated"],
  "description": "Production vault event handler",
  "status": "active",
  "createdAt": "2026-04-27T12:00:00Z"
}

List Subscriptions

GET /api/v1/orgs/{slug}/webhooks
webhooks:write
curl https://api.boxowl.me/api/v1/orgs/acme/webhooks \
  -H "X-API-Key: boxlive_01h455..."

Unsubscribe

DELETE /api/v1/orgs/{slug}/webhooks/{webhookId}
webhooks:write

Event Payload

BoxOwl sends an HTTP POST to your endpoint with a JSON body:

{
  "id": "evt_01h455vb4pex5vsknk084sn02q",
  "type": "consent.revoked",
  "timestamp": "2026-04-27T14:30:00Z",
  "organizationId": "org_01h455...",
  "data": {
    "connectionId": "con_01h455...",
    "userId": "usr_01h455...",
    "handle": "alice",
    "scope": "vault:read"
  }
}

Signature Verification

Each webhook request includes X-BoxOwl-Signature — an HMAC-SHA256 hex digest of the raw request body, signed with your API key secret.

Always verify signatures before processing payloads:

const crypto = require('crypto');
const sig = req.headers['x-boxowl-signature'];
const expected = crypto
  .createHmac('sha256', apiKeySecret)
  .update(rawBody)
  .digest('hex');
if (sig !== expected) {
  return res.status(401).send('Invalid signature');
}

Retry Policy

If your endpoint returns a non-2xx response or times out (10s), BoxOwl retries with exponential backoff:

After 5 failed attempts, the webhook is marked failed and no further retries occur. Inspect and replay from your dashboard.

← Back to API Reference