API Reference

Webhooks

Real-time event notifications for agent visits, optimization events, and alerts.

Webhooks

Webhooks deliver real-time HTTP POST callbacks to your server when events occur in your Inception Agents account. Use webhooks to build integrations that react to agent visits, optimization changes, and system alerts.


Setup

Configure your webhook endpoint in Dashboard > Settings > Webhooks.

  1. Enter your HTTPS endpoint URL.
  2. Select the event types you want to receive.
  3. Copy the signing secret for payload verification.
  4. Save the configuration.

Your endpoint must return a 2xx status code within 10 seconds to acknowledge receipt.


Payload Format

All webhook payloads follow this envelope structure:

{
  "event": "agent.visit",
  "data": { },
  "timestamp": "2026-02-27T12:00:00.000Z",
  "webhookId": "wh_a1b2c3d4e5f6"
}
FieldTypeDescription
eventstringEvent type identifier
dataobjectEvent-specific payload (see below)
timestampstringISO 8601 timestamp of when the event occurred
webhookIdstringUnique identifier for this webhook delivery

Event Types

agent.visit

Fired when an AI agent visits your site.

{
  "event": "agent.visit",
  "data": {
    "agentIdentity": "GPTBot",
    "provider": "openai",
    "path": "/pricing",
    "timestamp": "2026-02-27T12:00:00.000Z",
    "responseType": "full"
  },
  "timestamp": "2026-02-27T12:00:01.000Z",
  "webhookId": "wh_a1b2c3d4e5f6"
}

agent.referral

Fired when a user arrives at your site from an AI platform (e.g., a user clicks a link in a ChatGPT response).

{
  "event": "agent.referral",
  "data": {
    "provider": "chatgpt",
    "landingPage": "/pricing",
    "referrer": "https://chat.openai.com",
    "timestamp": "2026-02-27T12:05:00.000Z"
  },
  "timestamp": "2026-02-27T12:05:01.000Z",
  "webhookId": "wh_b2c3d4e5f6g7"
}

optimization.variant_winner

Fired when the optimization engine detects a new winning variant for a content chunk.

{
  "event": "optimization.variant_winner",
  "data": {
    "chunkId": "chunk_8f3a1b2c",
    "variantId": "var_002",
    "improvementPct": 12.5
  },
  "timestamp": "2026-02-27T13:00:00.000Z",
  "webhookId": "wh_c3d4e5f6g7h8"
}

content.honesty_flag

Fired when the honesty engine flags content that may be inaccurate or misleading.

{
  "event": "content.honesty_flag",
  "data": {
    "chunkId": "chunk_d4e5f6a7",
    "reason": "Statistical claim could not be verified against source data.",
    "severity": "warning"
  },
  "timestamp": "2026-02-27T14:00:00.000Z",
  "webhookId": "wh_d4e5f6g7h8i9"
}

The severity field is one of: info, warning, critical.

visibility.change

Fired when a significant change in AI visibility is detected for your domain.

{
  "event": "visibility.change",
  "data": {
    "metric": "citation_rate",
    "oldValue": 0.35,
    "newValue": 0.48,
    "platform": "openai"
  },
  "timestamp": "2026-02-27T15:00:00.000Z",
  "webhookId": "wh_e5f6g7h8i9j0"
}

integration.error

Fired when an integration encounters a health issue (e.g., edge worker misconfiguration, expired credentials).

{
  "event": "integration.error",
  "data": {
    "error": "Edge worker returned 500 for 15 consecutive requests.",
    "integration": "cloudflare_worker",
    "timestamp": "2026-02-27T16:00:00.000Z"
  },
  "timestamp": "2026-02-27T16:00:01.000Z",
  "webhookId": "wh_f6g7h8i9j0k1"
}

Signature Verification

Every webhook request includes an HMAC-SHA256 signature in the X-Inception-Signature header. Verify this signature to confirm the payload was sent by Inception Agents and has not been tampered with.

The signature is computed over the raw request body using your webhook signing secret.

Node.js Verification

import crypto from "node:crypto";

function verifyWebhookSignature(payload, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload, "utf-8")
    .digest("hex");

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

// Express middleware example
app.post("/webhooks/inception", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-inception-signature"];
  const secret = process.env.INCEPTION_WEBHOOK_SECRET;

  if (!verifyWebhookSignature(req.body.toString(), signature, secret)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = JSON.parse(req.body.toString());

  switch (event.event) {
    case "agent.visit":
      console.log(`Agent visit: ${event.data.agentIdentity} on ${event.data.path}`);
      break;
    case "optimization.variant_winner":
      console.log(`New winner: ${event.data.variantId} (+${event.data.improvementPct}%)`);
      break;
    default:
      console.log(`Unhandled event: ${event.event}`);
  }

  res.status(200).json({ received: true });
});

Python Verification

import hashlib
import hmac

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

    return hmac.compare_digest(signature, expected)

Retry Behavior

If your endpoint does not return a 2xx status code within 10 seconds, the delivery is retried with exponential backoff:

AttemptDelay After Failure
11 second
210 seconds
360 seconds

After 3 failed attempts, the delivery is marked as failed. Events older than 24 hours are dropped and will not be retried.

Failed deliveries are visible in Dashboard > Settings > Webhooks > Delivery Log.


Idempotency

Use the webhookId field to deduplicate deliveries. If your endpoint receives the same webhookId more than once (due to retries or network issues), discard the duplicate:

const processedWebhooks = new Set();

app.post("/webhooks/inception", (req, res) => {
  const event = req.body;

  if (processedWebhooks.has(event.webhookId)) {
    return res.status(200).json({ received: true, duplicate: true });
  }

  processedWebhooks.add(event.webhookId);
  // Process the event...

  res.status(200).json({ received: true });
});

In production, store processed webhook IDs in a persistent store (e.g., Redis, database) rather than an in-memory Set.


Testing

Dashboard Webhook Tester

Use the built-in tester in Dashboard > Settings > Webhooks to send a test payload to your endpoint. Select an event type and click Send Test to trigger a delivery with sample data.

API Test Endpoint

Send a test webhook programmatically:

curl -X POST "https://inception-agents-api.inception-agents.workers.dev/api/v1/webhooks/test" \
  -H "Authorization: Bearer iak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "agent.visit"
  }'

Response 200 OK

{
  "delivered": true,
  "webhookId": "wh_test_a1b2c3d4",
  "statusCode": 200,
  "responseTimeMs": 142
}

Best Practices

Respond quickly. Return a 2xx response as soon as possible. Process the event asynchronously (e.g., add to a queue) rather than performing long-running work in the request handler.

Verify signatures. Always validate the X-Inception-Signature header before processing the payload. Reject requests with missing or invalid signatures.

Handle duplicates. Track webhookId values to ensure idempotent processing.

Use HTTPS. Webhook endpoints must use HTTPS. HTTP endpoints are rejected during configuration.

Monitor delivery health. Check the delivery log in the dashboard regularly. Persistent failures may indicate endpoint issues or network problems.