Webhooks & events
Receive real-time call events at your own endpoint.
Webhooks let your systems react to calls as they happen, without polling. When an event fires, oyehello sends an HTTP POST to a URL you control with a JSON payload describing what happened.
Configure an endpoint
Webhook endpoints are configured per agent (or per workspace for account-wide events) in the console under Settings → Webhooks, or on the API via the agent’s webhookUrl. An endpoint must:
- Be reachable over HTTPS.
- Respond within 10 seconds with a
2xxstatus. Anything else is treated as a failure and retried.
Delivery & retries
Deliveries are at-least-once. A failed delivery (non-2xx, timeout, or connection error) is retried with exponential backoff for up to 24 hours. Design your handler to be idempotent - key off the event id so a re-delivered event isn’t processed twice.
Each request includes headers:
Content-Type: application/json
X-Oyehello-Event: call.completed
X-Oyehello-Signature: t=1699999999,v1=<hex>
Verify the signature
Every request is signed with your endpoint’s signing secret (shown once when the endpoint is created). Compute an HMAC-SHA256 of "{t}.{raw_body}" with the secret and compare it, in constant time, to the v1 value in the X-Oyehello-Signature header. Reject the request if it doesn’t match or if t is older than a few minutes.
Event types
| Event | Fires when |
|---|---|
call.started |
The call connected and the agent began. |
call.completed |
The call ended. Includes duration, disposition, and outcome. |
call.failed |
The call could not be placed or connect (busy, no-answer, blocked by a gate). |
transcript.ready |
The diarized transcript + any extracted fields are available. |
recording.ready |
The call recording is available (if recording is enabled). |
Payload
{
"id": "evt_9f2c…",
"type": "call.completed",
"createdAt": "2026-08-20T12:00:00Z",
"data": {
"callId": "call_1a2b…",
"agentId": "agt_…",
"toNumber": "+9198…",
"status": "completed",
"durationSeconds": 96,
"disposition": "interested",
"externalRef": "your-own-id"
}
}
Use data.externalRef (the value you passed when placing the call) to correlate the event back to a record in your own system. Fetch the full transcript and extracted fields from the Calls reference endpoint using data.callId.