Webhooks.

Receive real-time event deliveries when a turn is logged for review or gains a signal. Connect AgentLoop to your own systems for operational alerting.

Configure

Set up your endpoint URL and signing secret in the dashboard's Webhooks page. Each webhook has a unique URL, a signing secret shown once at creation, and a list of events it subscribes to.

Where to configure

Sign in to app.getagentloop.io and go to Webhooks in the sidebar. Admin role required.

Events

Payload

Every event has the same envelope. The data block contains the turn.

json
{
  "id": "evt_01h9...",
  "event": "turn.signal_received",
  "created_at": "2026-04-26T18:42:13.482Z",
  "api_version": "2026-04-26",
  "org_id": "org_abc",
  "delivery": { "id": "whd_...", "attempt": 1, "webhook_id": "wh_..." },
  "data": {
    "turn": {
      "id": "turn_abc",
      "question": "Can enterprise customers request a refund after 60 days?
      "agent_response": "...",
      "user_id": "u_42",
      "signals": { "thumbs_down": true },
      "duplicate_count": 1,
      "tags": [],
      "model": "gpt-4o",
      "dashboard_url": "https://app.getagentloop.io/review?turn_id=turn_abc"
    },
    "new_signals": ["thumbs_down"]
  }
}

Verify the signature

Every request includes X-AgentLoop-Signature: t=<unix>,v1=<hex>. Reject requests whose signature doesn't match — anyone with your URL could otherwise post fake events to it.

python · flask
import hmac, hashlib, time
SECRET = "whsec_..."  # the secret shown once when you created the webhook

@app.post("/webhook/agentloop")
def receive():
    raw = request.get_data(as_text=True)
    header = request.headers.get("X-AgentLoop-Signature", "")
    parts = dict(p.split("=", 1) for p in header.split(","))
    ts, v1 = int(parts["t"]), parts["v1"]
    if abs(time.time() - ts) > 300:
        return "stale", 400
    expected = hmac.new(
        SECRET.encode(), f"{ts}.{raw}".encode(), hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(v1, expected):
        return "bad signature", 403
    # ... process the event
    return "", 200

Custom headers

Headers are included with every webhook delivery. Use them for authentication or integration-specific requirements such as API keys or bearer tokens. Up to 5 custom headers can be configured per webhook.

Reserved names like Content-Type, User-Agent, and X-AgentLoop-* cannot be set (we manage those ourselves).

Retries

AgentLoop retries transient delivery failures automatically. Permanent configuration errors stop retrying so you can fix the endpoint. Every attempt is recorded in the delivery log, and past deliveries can be resent from the dashboard.