Your own systems — a CRM, a billing job, a compliance archive — often must react the moment a call changes state. Examples: a new call came in, the call was answered, the call transferred to a human, or the call hung up with a given cause. Voice events exist for this purpose. The engine emits one event for every lifecycle transition of a call, keyed by call_sid. You consume the events in one of two ways: as signed HTTP POSTs to an endpoint that you register, or off the real-time event bus that your app already subscribes to.
The events on this page are shipped and flow on every call today. They are the same records that power reports and dashboards. Programmable per-endpoint HTTP webhooks for voice ride the same signed-delivery system that powers ClutchCall Streams. The signing, retry, and delivery log below are that system. Voice event-type registration is rolling out on that shared delivery plane. Check in the console which call.* types your workspace can subscribe to before you depend on push delivery. Use the real-time bus or the observability pipeline in the meantime.

What you can subscribe to

Every event is named call.<state>. One call produces a stream of these events from initiated through cleared.
An AI agent or a human agent handled each segment that carries a handler_id. Downstream reporting uses this field to split a call into its AI leg and its human leg. Use it to attribute events to the agent that owned that stretch of the call.
Subscribe to a set of exact names, or use * to receive everything. A prefix glob such as call.* matches every call event.

Event payload

Every event is a flat JSON object. Only the fields that the engine actually knows for that transition are present. Absent fields are omitted, not null.
string
required
The universal call identifier. Correlate every event, the CDR, recordings, and the audio bridge through this one key.
string
required
The lifecycle state, e.g. established or cleared. The call. prefix is on the event name; the payload does not repeat it.
string
required
The workspace that owns the call.
integer
required
The event time in milliseconds since the Unix epoch. Use it to order events and to reject stale re-deliveries.
integer
The Q.850 clearing cause on cleared/failed (e.g. 16 = normal clearing). On call.dtmf this field carries the detected digit.
integer
The billable talk duration in seconds. Present on cleared.
string
The calling number (the “from”).
string
The dialed number (the “to”).
string
inbound or outbound.
string
The SIP trunk that the call matched or used.
string
The agent that owns this segment, when the engine knows it (AI or outbound).
Over HTTP, this object is the raw POST body. Over the real-time bus, the same object arrives as the data field of a call.<state> message. The message channel has a workspace scope.

Register an endpoint

You set up endpoints in the console, on the same Webhooks screen that all products use. Each endpoint gets its own HMAC signing secret.
1

Add an endpoint

Open Webhooks in the voice console (agent.clutchcall.dev). Click Add endpoint. Enter the HTTPS URL plus the event types to receive. The event types are a comma-separated list, where * matches everything (e.g. call.*).
2

Store the signing secret

On create, the console shows the per-endpoint signing secret once. The secret looks like whsec_…. Copy it and set it on your receiver. It never appears again.
The console shows the secret only at creation. You cannot retrieve it later. If you lose the secret, delete the endpoint and add it again to mint a new one.
3

Pause, resume, or delete

Each row shows a health state: Healthy, Paused, or Failing (Nx) after N consecutive non-2xx responses. Pause to stop deliveries without loss of the endpoint. Delete to remove the endpoint (its delivery history stays in the logs).

Verify the signature

Every delivery is signed. The engine’s delivery worker computes HMAC-SHA256(secret, rawBody) and sends it as a hex digest in a signature header. Recompute the digest over the exact bytes that you received, before any JSON parse. Compare the digests in constant time. Reject any delivery that does not match. Also reject payloads whose timestamp_ms is far outside your clock tolerance, to blunt replays.
Verify against the raw request bytes. If a framework parses and re-serializes the JSON before you hash it, the key order and whitespace change. Every signature then fails. Capture the body raw on this route.

Delivery, retry, and inspection

  • Acknowledge with 2xx. Any 2xx response marks the delivery successful. The worker treats any other status (or a timeout / connection error) as a failure and retries with backoff.
  • Retries. The delivery worker re-fires failed deliveries automatically, with increasing spacing. After a run of consecutive failures, the endpoint flips to Failing (Nx). Sustained failure pauses the endpoint, so a dead receiver cannot back up the queue.
  • Delivery log. The console keeps a per-delivery record: event type, target object, endpoint, response code, a short response-body preview, attempt number, and timestamp. You can filter the log by All / Delivered / Failed.
  • Resend. You can re-queue any delivery row from the log with Resend. Resend re-fires the same event within seconds. Use it after you fix a receiver that returned errors.
Make your handler idempotent. Because of retries and manual resends, the same (call_sid, event, timestamp_ms) can arrive more than once. Dedupe on that tuple. Do not assume exactly-once delivery.

Consume events without an endpoint

You do not have to run a public HTTPS receiver. The same events are available in two other places today:

Real-time event bus

call.<state> messages publish live on a workspace-scoped channel — the same bus that the agent control channel and consoles subscribe to. Best to drive a UI in real time.

Observability pipeline

The pipeline folds every lifecycle transition per call_sid into the durable reporting store behind dashboards and CDRs. Best for after-the-fact reporting and reconciliation.

Calls API

Originate, look up, transfer, and hang up — the control plane for the call_sid that these events key off.

Call traces

Follow one call end-to-end across signalling, media, and the agent runtime.

Agent control channel

The event surface for human-agent softphones: offers, state changes, accept and reject.

Errors

The status codes and failure causes that you will see on call.failed and call.cleared.