Webhook events reference

Webhook events reference

Telenow delivers events to the endpoints you register as signed HTTP POSTs. This page covers the delivery format, signature verification, retries, and the full event catalog with payloads. For a working receiver, see Receive & verify webhooks; to register an endpoint, see the Webhook management API.

The same events fire for every conversation — AI phone calls, manual / softphone calls, browser web calls, the public widget, and Chat API sessions — so one receiver can ingest them all. That makes them the channel that delivers recordings and call data back to a CRM after a click-to-call.

Event catalog at a glance

EventFires when
call.starteda call/chat session becomes active
call.endedthe conversation finishes (optionally enriched with recording + transcript)
transcript.readyeach finalized transcript turn during the conversation
tool.invokedthe agent calls a configured tool/function
recording.readya recording is finalized and stored (may land shortly after the call)
call.analyzedpost-call analysis completes

Subscribe to specific names with the events array, or ["*"] for all — see Subscribing.

Delivery format

Each event is an HTTP POST to your endpoint URL with a JSON body and these headers:

HeaderValue
Content-Typeapplication/json
X-VoiceAI-Eventthe event type, e.g. call.ended
X-VoiceAI-Signaturesha256=<hex> — HMAC‑SHA256 of the raw body, keyed with your endpoint's signing secret
X-VoiceAI-Deliverya unique delivery id (use it to de‑duplicate retries)

Respond with any 2xx to acknowledge. Non‑2xx, timeouts, and connection errors are treated as failures and retried.

Signature verification

Every delivery is signed so you can prove it came from Telenow and wasn't tampered with. Compute HMAC‑SHA256 over the raw request body using the endpoint's signing_secret (returned once when you create the endpoint), hex‑encode it, and compare (constant‑time) against the hex portion of X-VoiceAI-Signature (sha256=<hex>).

Verify against the raw bytes of the body — not a re-serialized object, which would change the JSON and break the comparison. Full Node and Python examples are in the integration guide.

Endpoints must be HTTPS. Plain http://, loopback, and private/cloud-metadata IPs are rejected at registration time (SSRF guard).

Retries

Failed deliveries (non-2xx, timeout, or connection error) retry with exponential backoff (5s × 2^attempt, capped at 1 hour) for up to 8 attempts, then the delivery is marked dead. After repeated permanent failures the endpoint itself is disabled. A receiver that replies 410 Gone is unsubscribed immediately (the REST-hooks convention) rather than retried. Inspect every attempt via GET /api/orgs/{orgId}/webhooks/{id}/deliveries.

Events

call.started

Fires when a call becomes active. variables carries the call's context variables (null when the call had none); call.ended includes the same field.

{
  "event": "call.started",
  "sessionId": "…",
  "agentId": "…",
  "userId": "…",
  "from": "+14155550123",
  "variables": { "customer_name": "Alex", "plan": "Pro" },
  "startTime": "2026-06-08T12:00:00Z"
}

call.ended

Fires when a call finishes. Optionally enriched with the recording and/or transcript when the endpoint opts in (include_recording / include_transcript).

{
  "event": "call.ended",
  "sessionId": "…",
  "agentId": "…",
  "userId": "…",
  "durationSecs": 142,
  "messageCount": 18,
  "fromOrTo": "+14155550123",
  "variables": { "customer_name": "Alex", "plan": "Pro" },

  "recording": { "id": "…", "url": "https://… (signed)", "expiresAt": "2026-06-08T13:00:00Z" },
  "transcript": [
    { "role": "user", "text": "Hi, I need to reschedule.", "at": "2026-06-08T12:00:05Z" },
    { "role": "assistant", "text": "Sure — what date works?", "at": "2026-06-08T12:00:08Z" }
  ]
}

recording and transcript are present only when the endpoint enabled them and the data exists at call end. For recordings that finalize slightly later, rely on recording.ready instead.

recording.ready

Fires when a recording is finalized and stored — including recordings that land shortly after the call ends. Carries a fresh signed URL.

{
  "event": "recording.ready",
  "recordingId": "…",
  "sessionId": "…",
  "agentId": "…",
  "durationSecs": 142,
  "recording": { "id": "…", "url": "https://… (signed, ~1h)", "expiresAt": "2026-06-08T13:00:00Z" }
}

transcript.ready

Fires per finalized transcript turn during a call.

{
  "event": "transcript.ready",
  "sessionId": "…",
  "role": "user",
  "text": "I'd like to check my order status."
}

tool.invoked

Fires when the agent calls a configured tool/function.

{
  "event": "tool.invoked",
  "sessionId": "…",
  "agentId": "…",
  "name": "lookup_order",
  "arguments": { "orderId": "A-1234" },
  "result": { "status": "shipped" },
  "status": "ok",
  "latencyMs": 320
}

status is "ok" or "error"; latencyMs is the tool round-trip time.

call.analyzed

Fires when post-call analysis completes for a call (shortly after call.ended, only when analysis is enabled for the agent). Carries the structured analysis result.

{
  "event": "call.analyzed",
  "sessionId": "…",
  "analysis": {
    "summary": "Customer asked about an order and the agent confirmed it shipped.",
    "sentiment": "positive",
    "sentimentScore": 0.8,
    "disposition": "resolved",
    "actionItems": ["Email the tracking link to the customer"],
    "topics": ["order status"],
    "keywords": ["order", "shipping"],
    "score": 9,
    "talkRatio": { "agentWords": 120, "customerWords": 80, "agentTurns": 9, "customerTurns": 9 },
    "model": "…"
  }
}

The analysis object may also include customData, evidence, qa, objections, coaching, hallucinations, and cx sections depending on the agent's analysis configuration — present only when those checks are enabled. See Post-call analysis.

Subscribing

Choose events per endpoint with the events array (or ["*"] for all), and scope to an agent with agentId/agent_id. You can register endpoints two ways — the dashboard Webhooks page / management API, or the REST-hooks API used by automation platforms — both documented in Webhook management.