Allerto API

Webhooks

Allerto posts JSON events to the URL in the agent's delivery (or to a call's callback_url).

EventWhen
call.completedOnce per call, when it has ended for good: with outcome, result, summary, sentiment
call.attempt_failedAn outbound attempt was not answered and another is scheduled (next_attempt_at)
{
  "id": "evt-uuid",
  "type": "call.completed",
  "version": "2",
  "created_at": "2026-09-21T14:29:14Z",
  "livemode": true,
  "partner_id": "…",
  "call": { "…": "the call object, see Calls and campaigns" }
}

livemode: false marks events produced by test keys. For inbound agents with review: on_issues, the event is sent after an operator approves the data when something was missing.

Signing secret

One secret per account signs every event:

POST /v1/webhook-secret        →  {"secret": "whsec_…"}
allerto webhook-secret rotate

It is shown once. Rotating affects new events; events already queued keep the previous secret. An agent whose delivery uses a webhook cannot be published until a secret exists.

Verify every request

Headers:

Content-Type: application/json
Idempotency-Key: <event id>
X-Allerto-Event-Id: <event id>
X-Allerto-Timestamp: <unix seconds>
X-Allerto-Signature: sha256=<hex HMAC-SHA256 of "<timestamp>.<raw body>">

Node.js:

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, headers, secret) {
  const ts = headers["x-allerto-timestamp"];
  const got = Buffer.from(
    String(headers["x-allerto-signature"]).replace(/^sha256=/, ""),
    "hex",
  );
  const want = createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest();
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && got.length === want.length && timingSafeEqual(got, want);
}

Python:

import hmac, hashlib, time

def verify(raw_body: bytes, headers, secret: str) -> bool:
    ts = headers["X-Allerto-Timestamp"]
    got = headers["X-Allerto-Signature"].removeprefix("sha256=")
    want = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return abs(time.time() - int(ts)) < 300 and hmac.compare_digest(got, want)

Always verify against the raw body, before parsing JSON.

Delivery guarantees

Email delivery

Inbound agents can also send each result by email (delivery.mode: "email" or "both"), with the subject and introduction you configure and, optionally, a short AI summary. Test keys never send emails.