Appearance
Webhook events
Every event Talkline sends to a registered endpoint, with the fields its data carries. How to receive them safely is the webhooks guide.
The envelope
Every delivery's body. Deliveries are at least once: the receiver is idempotent on id, which is the X-Talkline-Delivery header and stable across retries.
| Field | Type | Description |
|---|---|---|
id | string | |
event | string | One of room.started, room.finished, participant.joined, participant.left, call.ringing, call.answered, call.ended, call.missed, call.rejected, call.cancelled, queue.entered, queue.assigned, queue.abandoned, queue.overflowed, recording.started, recording.finished, recording.failed, usage.threshold. |
createdAt | string (date-time) | |
data | object | The event's fields, times as ISO 8601. |
Headers
| Name | In | Type | Description |
|---|---|---|---|
X-Talkline-Signature | header | string | t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "{t}.{raw body}")>. Verify over the raw bytes received, compare in constant time, and reject a t more than five minutes from now. Matches ^t=\d+,v1=[0-9a-f]{64}$. |
X-Talkline-Event | header | string | One of room.started, room.finished, participant.joined, participant.left, call.ringing, call.answered, call.ended, call.missed, call.rejected, call.cancelled, queue.entered, queue.assigned, queue.abandoned, queue.overflowed, recording.started, recording.finished, recording.failed, usage.threshold. |
X-Talkline-Delivery | header | string | The delivery's idempotency key, equal to the envelope's id. Stable across retries. |
Acknowledging
Any 2xx acknowledges the delivery. Anything else — another status, a timeout, a redirect — is a failed attempt, retried after 10 s, 1 min, 5 min, 30 min, 2 h and 6 h, then abandoned. Twenty consecutive failures park the endpoint failing until a human resumes it.
room.started not sent yet
A room's first participant joined.
data
The event's fields, times as ISO 8601.
room.finished
A room ended.
data
| Field | Type | Description |
|---|---|---|
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
participant.joined not sent yet
A participant joined a room.
data
The event's fields, times as ISO 8601.
participant.left not sent yet
A participant left a room.
data
The event's fields, times as ISO 8601.
call.ringing
A call rang its invitees.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
to | string[] | |
media | string | One of audio, video. |
needsPush | boolean | True when no device of the invitee's could be reached — the tenant's cue to push from its own token store. |
call.answered
A call was answered.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
by | string | The identity that answered. |
answeredAt | string (date-time) |
call.ended
A call ended — the billing trigger.
Sent when an answered call ends, and also when the room of a call still ringing is ended under it — evicted or node_failure, say — with durationSec and billableSec null. A call that rang out, was declined or was cancelled sends call.missed, call.rejected or call.cancelled instead: exactly one of the four arrives for each call, at each endpoint subscribed to it.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
endReason | string | Why a call ended: the call's own record, the same whichever side reads it. hangup — the identity that placed the call hung up (a queue call's caller included); remote_hangup — the other side hung up: the callee, or the member who answered a queue call. A participant whose connection was lost and did not come back in time, or who was removed from the room, counts as hanging up. no_answer — nobody answered before the ring timeout, nobody could be reached, or a queue gave up; rejected — the callee declined; cancelled — the caller gave up while it rang; evicted — the room was ended, through this API or by a participant allowed to end it; quota_exhausted — a quota or an identity's credit ran out; node_failure — a server failed and the call could not be carried over; max_duration — the room reached its longest allowed duration. busy, reconnect_timeout and transport_failure are not recorded today. The web SDK's callEnded reports hangup and remote_hangup from the client's own side instead: hangup when that client hung up. One of hangup, remote_hangup, no_answer, rejected, cancelled, busy, reconnect_timeout, transport_failure, evicted, quota_exhausted, node_failure, max_duration. |
durationSec | integer | null | From answer to end; null for a call never answered. |
billableSec | integer | null | Participant seconds in the call, rounded up to the increment; null for a call never answered. |
endedAt | string (date-time) |
call.missed
A call rang out unanswered.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
endReason | string | Why a call ended: the call's own record, the same whichever side reads it. hangup — the identity that placed the call hung up (a queue call's caller included); remote_hangup — the other side hung up: the callee, or the member who answered a queue call. A participant whose connection was lost and did not come back in time, or who was removed from the room, counts as hanging up. no_answer — nobody answered before the ring timeout, nobody could be reached, or a queue gave up; rejected — the callee declined; cancelled — the caller gave up while it rang; evicted — the room was ended, through this API or by a participant allowed to end it; quota_exhausted — a quota or an identity's credit ran out; node_failure — a server failed and the call could not be carried over; max_duration — the room reached its longest allowed duration. busy, reconnect_timeout and transport_failure are not recorded today. The web SDK's callEnded reports hangup and remote_hangup from the client's own side instead: hangup when that client hung up. One of hangup, remote_hangup, no_answer, rejected, cancelled, busy, reconnect_timeout, transport_failure, evicted, quota_exhausted, node_failure, max_duration. |
durationSec | integer | null | From answer to end; null for a call never answered. |
billableSec | integer | null | Participant seconds in the call, rounded up to the increment; null for a call never answered. |
endedAt | string (date-time) |
call.rejected
A call was rejected.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
endReason | string | Why a call ended: the call's own record, the same whichever side reads it. hangup — the identity that placed the call hung up (a queue call's caller included); remote_hangup — the other side hung up: the callee, or the member who answered a queue call. A participant whose connection was lost and did not come back in time, or who was removed from the room, counts as hanging up. no_answer — nobody answered before the ring timeout, nobody could be reached, or a queue gave up; rejected — the callee declined; cancelled — the caller gave up while it rang; evicted — the room was ended, through this API or by a participant allowed to end it; quota_exhausted — a quota or an identity's credit ran out; node_failure — a server failed and the call could not be carried over; max_duration — the room reached its longest allowed duration. busy, reconnect_timeout and transport_failure are not recorded today. The web SDK's callEnded reports hangup and remote_hangup from the client's own side instead: hangup when that client hung up. One of hangup, remote_hangup, no_answer, rejected, cancelled, busy, reconnect_timeout, transport_failure, evicted, quota_exhausted, node_failure, max_duration. |
durationSec | integer | null | From answer to end; null for a call never answered. |
billableSec | integer | null | Participant seconds in the call, rounded up to the increment; null for a call never answered. |
endedAt | string (date-time) |
call.cancelled
A call was cancelled before it was answered.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
endReason | string | Why a call ended: the call's own record, the same whichever side reads it. hangup — the identity that placed the call hung up (a queue call's caller included); remote_hangup — the other side hung up: the callee, or the member who answered a queue call. A participant whose connection was lost and did not come back in time, or who was removed from the room, counts as hanging up. no_answer — nobody answered before the ring timeout, nobody could be reached, or a queue gave up; rejected — the callee declined; cancelled — the caller gave up while it rang; evicted — the room was ended, through this API or by a participant allowed to end it; quota_exhausted — a quota or an identity's credit ran out; node_failure — a server failed and the call could not be carried over; max_duration — the room reached its longest allowed duration. busy, reconnect_timeout and transport_failure are not recorded today. The web SDK's callEnded reports hangup and remote_hangup from the client's own side instead: hangup when that client hung up. One of hangup, remote_hangup, no_answer, rejected, cancelled, busy, reconnect_timeout, transport_failure, evicted, quota_exhausted, node_failure, max_duration. |
durationSec | integer | null | From answer to end; null for a call never answered. |
billableSec | integer | null | Participant seconds in the call, rounded up to the increment; null for a call never answered. |
endedAt | string (date-time) |
queue.entered
A call entered a queue.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
queueId | string (uuid) | |
queueSlug | string | null | Null when the queue was deleted under the entry. |
caller | string | |
requiredSkills | string[] | |
enqueuedAt | string (date-time) |
queue.assigned
A queued call was answered by the member it was offered to.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
queueId | string (uuid) | |
queueSlug | string | null | Null when the queue was deleted under the entry. |
caller | string | |
requiredSkills | string[] | |
enqueuedAt | string (date-time) | |
attempts | integer | Members offered the call, the one who answered included. At least 1. |
assignedIdentity | string | |
assignedAt | string (date-time) |
queue.abandoned
A caller left a queue before a member answered.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
queueId | string (uuid) | |
queueSlug | string | null | Null when the queue was deleted under the entry. |
caller | string | |
requiredSkills | string[] | |
enqueuedAt | string (date-time) | |
attempts | integer | Members offered the call before the caller left. At least 0. |
abandonedAt | string (date-time) |
queue.overflowed
Nobody was eligible, and the queue's overflow action is webhook.
data
| Field | Type | Description |
|---|---|---|
callSid | string | Matches ^CS_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
queueId | string (uuid) | |
queueSlug | string | null | Null when the queue was deleted under the entry. |
caller | string | |
requiredSkills | string[] | |
enqueuedAt | string (date-time) | |
attempts | integer | Members offered the call before nobody was left. At least 0. |
overflowedAt | string (date-time) |
recording.started
A recording started.
Sent once the recorder has it; its participants were told before.
data
| Field | Type | Description |
|---|---|---|
recordingSid | string | Matches ^RC_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
consentRequired | boolean | |
startedAt | string (date-time) |
recording.finished
A recording's files are uploaded.
Sent once a recording that stopped as asked — or with its room — has every file in the object store, with the files. Fetch them with GET /v1/recordings/{sid}/url. Exactly one of recording.finished and recording.failed arrives for each recording.
data
| Field | Type | Description |
|---|---|---|
recordingSid | string | Matches ^RC_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
status | string | starting and active while it records; stopping and processing while its files are finished and uploaded; then complete, or failed — stopped by something other than a request, or never started — with whatever it captured (partial). One of starting, active, stopping, processing, complete, failed. |
layout | string | One of per_track, composite, audio_only. |
consentRequired | boolean | |
partial | boolean | |
error | string | null | |
startedAt | string (date-time) | |
endedAt | string (date-time) | null | |
durationSec | integer | null | |
sizeBytes | integer | null | |
storageKey | string | null | |
expiresAt | string (date-time) | null | |
deletedAt | string (date-time) | null | |
files | RecordingFile[] |
recording.failed
A recording stopped by a failure.
Sent when a recording stopped by something other than a request — its media server or its recorder went — has what it captured uploaded (partial, with files), or never started (no files). Its participants were told it failed.
data
| Field | Type | Description |
|---|---|---|
recordingSid | string | Matches ^RC_[0-9a-f]{20}$. |
roomSid | string | Matches ^RM_[0-9a-f]{20}$. |
status | string | starting and active while it records; stopping and processing while its files are finished and uploaded; then complete, or failed — stopped by something other than a request, or never started — with whatever it captured (partial). One of starting, active, stopping, processing, complete, failed. |
layout | string | One of per_track, composite, audio_only. |
consentRequired | boolean | |
partial | boolean | |
error | string | null | |
startedAt | string (date-time) | |
endedAt | string (date-time) | null | |
durationSec | integer | null | |
sizeBytes | integer | null | |
storageKey | string | null | |
expiresAt | string (date-time) | null | |
deletedAt | string (date-time) | null | |
files | RecordingFile[] |
usage.threshold
A quota reached a configured percentage, or an identity's credit is about to run out.
kind: quota — a quota reached one of settings.metering.thresholds, once per quota, percentage and period. kind: credit — an enrolled identity's balance runs out at endsAt, about a minute ahead, at the rate it is using it; its seats end then unless credit arrives.
data
object