Webhooks

Receive conversation events on an HTTPS endpoint.

Webhooks notify your server when an AI or human message is stored on a public API conversation, and when the agent requests a human handoff.

Create and delete endpoints with the Webhooks API. The signing secret is returned only on create — store it immediately.

These events are delivered only to endpoints you create through this API. They are not sent to Zapier, Make, or n8n dashboard webhooks.

Events

EventWhen it fires
public_api_message_createdAfter an AI reply is stored on a public API conversation, and after every human reply on a public API conversation (API or dashboard). It does not fire for visitor sends.
public_api_human_handoffWhen the AI requests human support on a public API conversation.

Widget and email threads do not trigger these events. A dashboard human reply on a public API thread still notifies your endpoint.

Deliveries are queued. Failed deliveries are retried up to three times (after 60 seconds, 5 minutes, and 15 minutes). Respond with 2xx to acknowledge.

Payloads

Every delivery is a JSON POST. Top-level id is the conversation UUID.

public_api_message_created

{
  "id": "3f1a9c2e-8b4d-4e6a-9c1f-2a3b4c5d6e7f",
  "event": "public_api_message_created",
  "timestamp": "2026-09-05T10:16:05+00:00",
  "data": {
    "conversation": { "id": "3f1a9c2e-8b4d-4e6a-9c1f-2a3b4c5d6e7f" },
    "message": {
      "id": "a1b2c3d4-e5f6-4708-9a1b-2c3d4e5f6071",
      "role": "assistant",
      "content": "Here is the AI reply."
    }
  }
}

role is assistant for AI replies and human for human replies. It is never visitor for this event.

public_api_human_handoff

{
  "id": "3f1a9c2e-8b4d-4e6a-9c1f-2a3b4c5d6e7f",
  "event": "public_api_human_handoff",
  "timestamp": "2026-09-05T10:17:00+00:00",
  "data": {
    "conversation": { "id": "3f1a9c2e-8b4d-4e6a-9c1f-2a3b4c5d6e7f" }
  }
}

Verifying deliveries

Each request includes:

HeaderMeaning
X-Webhook-SignatureHex HMAC‑SHA256 of the raw JSON body, keyed with the endpoint secret.
X-Webhook-Eventpublic_api_message_created or public_api_human_handoff.
X-Webhook-Delivery-IDDelivery identifier.
User-AgentAssistLoop-Webhooks/1.0.

Compute HMAC-SHA256(secret, raw_body) and compare it to X-Webhook-Signature with a constant‑time equals. Verify against the bytes you received — do not re‑serialize the parsed JSON.

Node.js
import crypto from 'node:crypto';

function isValidAssistLoopWebhook(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  const a = Buffer.from(signatureHeader, 'utf8');
  const b = Buffer.from(expected, 'utf8');

  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

The callback URL must be https:// and must not point at localhost or an internal IP.