API Reference

Webhooks

FORG can send HTTP POST notifications to your endpoints when important events occur. Webhooks are signed with HMAC-SHA256 so you can verify authenticity.

Register a webhook

POST /api/v1/webhooks
Content-Type: application/json
Authorization: Bearer forg_live_...

{
  "url":    "https://your-server.com/forg-webhook",
  "events": ["budget.exceeded", "rule.triggered", "anomaly.detected"],
  "secret": "your-webhook-secret-min-32-chars"
}
{
  "id":        "wh_9f3a2b1c",
  "url":       "https://your-server.com/forg-webhook",
  "events":    ["budget.exceeded", "rule.triggered", "anomaly.detected"],
  "enabled":   true,
  "created_at": "2025-05-28T10:00:00Z"
}

Webhook events

EventFired when
session.startedA new session begins
session.endedA session ends (timeout or explicit close)
budget.exceededA budget rule threshold is crossed
budget.warningA budget reaches 80% of its threshold
rule.triggeredAny rule fires (block, warn, notify, or log)
anomaly.detectedThe intelligence layer detects unusual activity

Payload schema

// All webhook payloads have this envelope:
{
  "id":       "wev_4a2b9c1d",
  "type":     "budget.exceeded",
  "org_id":   "org_abc123",
  "ts":       "2025-05-28T14:30:00Z",
  "data":     { ... }  // event-specific payload
}

// budget.exceeded data:
{
  "rule_id":    "rule_7b3c1d9e",
  "rule_name":  "Monthly $500 org budget",
  "scope":      "org",
  "scope_id":   "org_abc123",
  "threshold":  500,
  "current":    502.34,
  "window":     "monthly",
  "metric":     "cost_usd"
}

// rule.triggered data:
{
  "rule_id":    "rule_9a2b3c",
  "rule_name":  "Block GPT-4o",
  "action":     "block",
  "user_id":    "user_abc",
  "model":      "gpt-4o",
  "session_id": "sess_xyz",
  "event_id":   "evt_123"
}

// anomaly.detected data:
{
  "anomaly_type":   "token_spike",
  "user_id":        "user_abc",
  "baseline_avg":   1200,
  "observed":       9840,
  "deviation_pct":  720,
  "session_id":     "sess_xyz"
}

Verifying signatures

Each webhook request includes an X-Forg-Signature header containing an HMAC-SHA256 of the raw request body, signed with your webhook secret:

X-Forg-Signature: sha256=a3f9e2c1b84d7f6e0a2c1d8e9f0b3c4d...
// Node.js verification
import crypto from "crypto";

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(body, "utf8")
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// In your Express handler:
app.post("/forg-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.headers["x-forg-signature"] as string;
  if (!verifyWebhook(req.body.toString(), sig, process.env.FORG_WEBHOOK_SECRET!)) {
    return res.status(401).send("Invalid signature");
  }
  const event = JSON.parse(req.body.toString());
  console.log("Received:", event.type, event.data);
  res.sendStatus(200);
});

Retry policy

FORG retries failed webhook deliveries (non-2xx response or timeout) with exponential backoff:

  • Attempt 1: immediate
  • Attempt 2: 30 seconds
  • Attempt 3: 5 minutes
  • Attempt 4: 30 minutes
  • Attempt 5: 2 hours

After 5 failed attempts, the webhook is marked as failing and an alert is sent to the org admin. The webhook remains enabled but delivery is paused until you re-enable it in the dashboard.

Delivery timeout

Your endpoint must respond within 10 seconds. Return 200 immediately and process asynchronously if needed. Long-running handlers will cause retries.

List webhooks

GET /api/v1/webhooks

Delete a webhook

DELETE /api/v1/webhooks/:id

Test delivery

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

Sends a test session.started event to the endpoint.

© 2026 UpgradIQ, Inc.Edit this page on GitHub