Documentation

Webhooks

Receive real-time notifications when events happen in your Bolor Intelligence workspace. Webhooks push event data to your endpoint via HTTP POST requests.

Setting Up Webhooks

You can configure webhook endpoints through the dashboard or via the management API. Each webhook endpoint subscribes to one or more event types and receives HTTP POST requests with JSON payloads whenever those events occur.

Via the Dashboard

  1. Navigate to Settings > Webhooks in your dashboard
  2. Click Add Endpoint
  3. Enter your HTTPS endpoint URL
  4. Select the event types you want to receive
  5. Click Create and copy the signing secret

Via the API

curl
curl -X POST https://api.bolor.ai/v1/webhooks \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://your-app.com/webhooks/bolor",
  "events": [
    "agentguard.action.blocked",
    "agentguard.action.approved",
    "compliance.check.failed",
    "mindvault.memory.stored"
  ],
  "description": "Production event handler"
}'

# Response:
# {
#   "id": "wh_abc123",
#   "url": "https://your-app.com/webhooks/bolor",
#   "events": ["agentguard.action.blocked", ...],
#   "signing_secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxx",
#   "status": "active",
#   "created_at": "2026-02-14T12:00:00Z"
# }

Important: Your webhook endpoint must use HTTPS and respond with a 2xx status code within 30 seconds. Endpoints that consistently fail will be automatically disabled after 5 consecutive failures.

Event Types

Subscribe to specific event types to receive only the notifications you need. Events are organized by product.

AgentGuard Events

EventDescription
agentguard.action.approvedAn agent action was approved and executed
agentguard.action.blockedAn agent action was blocked by safety rules
agentguard.action.reviewAn agent action requires human review

ComplianceGraph Events

EventDescription
compliance.check.passedA compliance check passed all rules
compliance.check.failedA compliance check failed one or more rules
compliance.rule.updatedA compliance rule was created or modified

MindVault Events

EventDescription
mindvault.memory.storedA new memory entity was stored
mindvault.graph.updatedKnowledge graph relationships were modified

System Events

EventDescription
system.rate_limit.warningUsage reached 80% of rate limit
system.rate_limit.exceededRate limit was exceeded

Webhook Payload

Every webhook delivery sends a JSON payload with a consistent structure. The data field contains event-specific information.

JSON Payload
{
  "id": "evt_abc123def456",
  "type": "agentguard.action.blocked",
  "created_at": "2026-02-14T15:30:00Z",
  "workspace_id": "ws_xyz789",
  "data": {
    "action_id": "act_001",
    "agent_id": "agent_support_v2",
    "action_type": "api_call",
    "blocked_reason": "Exceeded spending limit",
    "rules_violated": ["max_transaction_amount"],
    "safety_score": 23,
    "proposed_action": {
      "tool": "payment_api",
      "method": "POST",
      "params": {"amount": 50000, "currency": "USD"}
    }
  }
}

Signature Verification

Every webhook request includes a signature in the X-Bolor-Signature header. You should verify this signature to ensure the request came from Bolor Intelligence and was not tampered with.

The signature is computed as an HMAC-SHA256 of the raw request body using your webhook signing secret.

Python Verification

python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    """Verify a Bolor Intelligence webhook signature."""
    expected = hmac.new(
        secret.encode("utf-8"),
        payload,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(f"sha256={expected}", signature)

# In your webhook handler (Flask example):
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_signing_secret"

@app.route("/webhooks/bolor", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-Bolor-Signature", "")
    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        abort(401, "Invalid signature")

    event = request.json
    event_type = event["type"]

    if event_type == "agentguard.action.blocked":
        # Handle blocked agent action
        print(f"Action blocked: {event['data']['blocked_reason']}")

    return "", 200

Node.js Verification

typescript
import crypto from "crypto";
import express from "express";

const app = express();
const WEBHOOK_SECRET = "whsec_your_signing_secret";

function verifyWebhook(payload: string, signature: string): boolean {
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(payload, "utf8")
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(`sha256=${expected}`),
    Buffer.from(signature)
  );
}

app.post("/webhooks/bolor", express.raw({ type: "*/*" }), (req, res) => {
  const signature = req.headers["x-bolor-signature"] as string;
  const payload = req.body.toString();

  if (!verifyWebhook(payload, signature)) {
    return res.status(401).send("Invalid signature");
  }

  const event = JSON.parse(payload);

  switch (event.type) {
    case "agentguard.action.blocked":
      console.log(`Action blocked: ${event.data.blocked_reason}`);
      break;
    case "compliance.check.failed":
      console.log(`Compliance failed: ${event.data.rules_violated}`);
      break;
  }

  res.status(200).send("OK");
});

Retry Policy

If your endpoint returns a non-2xx status code or times out (30 second limit), Bolor Intelligence will retry the delivery with exponential backoff.

AttemptDelayCumulative Time
1st retry1 minute1 minute
2nd retry5 minutes6 minutes
3rd retry30 minutes36 minutes
4th retry2 hours~2.5 hours
5th retry (final)8 hours~10.5 hours

After 5 failed retries, the event is marked as failed and will not be retried automatically. You can view failed deliveries in the dashboard and manually retry them.

Automatic disabling: If your endpoint fails to respond successfully 5 consecutive times across different events, the webhook will be automatically disabled. You will receive an email notification and can re-enable it from the dashboard.

Next Steps