Skip to content
Events

Webhooks

Webhooks let you receive real-time HTTP callbacks when events occur on the SIMOSphere AI platform. Instead of polling the API, you register an endpoint URL and the platform sends a POST request whenever a relevant event fires — enabling reactive architectures for usage monitoring, billing alerts, and automated workflows.

Setting Up a Webhook

Navigate to Settings → Webhooks in the SIMOSphere AI dashboard at app.simosphereai.com. Click Add Endpoint and provide the following:

  • Endpoint URL — the HTTPS URL that will receive webhook POST requests.
  • Events — select which event types to subscribe to (or subscribe to all).
  • Secret — a signing secret is generated automatically. Store it securely for signature verification.

Your endpoint must respond with a 2xx status code within 10 seconds. If the endpoint fails, the platform retries delivery with exponential backoff for up to 24 hours (attempts at 1 min, 5 min, 30 min, 2 hours, 12 hours, 24 hours).

Event Types

Each webhook delivery includes a JSON payload with an event field identifying the event type, a timestamp in ISO 8601 format, and a data object with event-specific details.

usage.threshold_reached

Fired when token usage reaches a configured percentage of the plan limit (default thresholds: 50%, 80%, 95%, 100%). Use this to trigger alerts or automatically upgrade the plan before requests start being rate-limited.

usage.daily_summary

Sent once daily at 00:00 UTC with a summary of the previous day's usage: total tokens, total requests, per-model breakdown, and estimated cost. Useful for daily reporting dashboards and cost tracking.

billing.invoice_created

Triggered when a new invoice is generated at the end of a billing cycle. Includes the invoice amount, line items, and a link to the invoice PDF for automated bookkeeping integration.

billing.payment_failed

Sent when a payment attempt fails. Contains the failure reason and the next retry date. Act on this event to notify account owners and prevent service interruption.

key.created / key.revoked

Fired when an API key is created or revoked. Includes the key name, scopes, and the identity of the user who performed the action. Essential for security audit trails.

model.status_changed

Sent when a model's availability status changes (e.g., from healthy to degraded, or when a new model becomes available). Includes the model ID, old status, and new status.

Payload Format

Every webhook delivery is an HTTP POST with a JSON body. The payload follows a consistent envelope format:

{
  "id": "evt_01J5K8M2N3P4Q5R6S7T8U9V0",
  "event": "usage.threshold_reached",
  "timestamp": "2026-06-06T14:30:00.000Z",
  "data": {
    "threshold": 80,
    "current_usage": 824000,
    "plan_limit": 1000000,
    "period": "2026-06",
    "key_id": "key_abc123"
  }
}

The id field is globally unique and can be used for idempotent processing — if you receive the same event ID twice, you should skip the duplicate.

Signature Verification

Every webhook request includes an X-Simosphere-Signature header containing an HMAC-SHA256 signature of the raw request body. Always verify this signature before processing the event to ensure the request originated from SIMOSphere AI and was not tampered with in transit.

Node.js Verification Example

import crypto from "node:crypto";

function verifyWebhookSignature(
  rawBody: string,
  signature: string,
  secret: string,
): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody, "utf8")
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

// In your Express handler:
app.post("/webhooks/simosphere", (req, res) => {
  const signature = req.headers["x-simosphere-signature"] as string;
  const rawBody = req.body; // must be the raw string, not parsed JSON

  if (!verifyWebhookSignature(rawBody, signature, WEBHOOK_SECRET)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = JSON.parse(rawBody);
  // Process the event...
  res.status(200).json({ received: true });
});

Python Verification Example

import hmac
import hashlib

def verify_webhook_signature(
    raw_body: bytes, signature: str, secret: str
) -> bool:
    expected = hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# In your Flask handler:
@app.route("/webhooks/simosphere", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-Simosphere-Signature", "")
    if not verify_webhook_signature(request.data, signature, WEBHOOK_SECRET):
        return {"error": "Invalid signature"}, 401

    event = request.get_json()
    # Process the event...
    return {"received": True}, 200

Best Practices

Respond Quickly

Return a 200 response immediately and process the event asynchronously in a background job. If your handler takes longer than 10 seconds, the platform will consider the delivery failed and schedule a retry.

Handle Duplicates

Due to retry logic, you may receive the same event more than once. Use the event id field to implement idempotent processing. Store processed event IDs and skip any duplicates.

Use HTTPS Only

Webhook endpoints must use HTTPS with a valid TLS certificate. The platform will reject plain HTTP URLs to protect the confidentiality of event payloads which may contain usage data and key identifiers.

Monitor Delivery Health

The dashboard shows delivery logs for each webhook endpoint including status codes, response times, and retry history. Set up alerts for persistent delivery failures so you can investigate endpoint issues before events are dropped.

Webhooks — SIMOSphere AI