Assistant event stream WebSocket channel
Single bidirectional channel carrying all assistant event stream messages.
Telnyx-to-customer frames: session.created, session.ended, error, the conversation and response events, the telnyx.* telephony events, and session.delegation.created.
Customer-to-Telnyx frames: conversation.item.create and session.delegation.completed.
{
"type": "session.created",
"session": {
"conversation_id": "0c1f4a2b-6f5d-11ef-9692-02420aeffb1f",
"assistant_id": "assistant-0b9c3d21",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"call_session_id": "ff55a038-6f5d-11ef-9692-02420aeffb1f",
"call_leg_id": "428c31b6-7af4-4b6f-92e7-7a7e6a4f1d44",
"from": "+13122010094",
"to": "+13122123456",
"direction": "inbound"
}
}{
"type": "session.ended",
"reason": "normal",
"duration_sec": 84,
"transfer_status": null
}{
"type": "conversation.item.created",
"previous_item_id": "msg_5f1c0a91",
"item": {
"id": "msg_7b2e4d10",
"type": "message",
"status": "completed",
"role": "user",
"name": null,
"participant_id": "participant_1",
"content": [
{
"type": "text",
"text": "What time do you close today?"
}
]
}
}{
"type": "conversation.item.deleted",
"item_id": "msg_9c1f4a2b"
}{
"type": "conversation.participant.added",
"participant": {
"id": "participant_2",
"role": "user",
"name": "Supervisor"
}
}{
"type": "conversation.participant.removed",
"participant": {
"id": "participant_2",
"role": "user",
"name": "Supervisor"
}
}{
"type": "response.created",
"response": {
"id": "resp_9c1f4a2b",
"status": "in_progress",
"output": []
}
}{
"type": "response.output_item.added",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"item": {
"id": "msg_9c1f4a2b",
"type": "message",
"status": "incomplete",
"role": "assistant",
"name": "Support Assistant",
"content": []
}
}{
"type": "response.content_part.added",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"content_index": 0,
"item_id": "msg_9c1f4a2b",
"part": {
"type": "text",
"text": ""
}
}{
"type": "response.text.delta",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"content_index": 0,
"item_id": "msg_9c1f4a2b",
"delta": "We are open "
}{
"type": "telnyx.call.answered",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ"
}{
"type": "telnyx.call.hangup",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"cause": "normal_clearing"
}{
"type": "telnyx.call.dtmf.received",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"digit": "1"
}{
"type": "telnyx.call.machine.detection.ended",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"result": "human"
}{
"type": "telnyx.call.transfer.completed",
"target": "+13125550100"
}{
"type": "telnyx.call.transfer.failed",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"target": "sip:support@example.com",
"status": "486"
}{
"type": "telnyx.assistant.handoff",
"assistant_id": "assistant-4d8e1f37"
}{
"type": "session.delegation.created",
"delegation": {
"id": "5b1d9e02-4c77-4f3a-8a2e-1c6f0b9d7a54",
"request": null,
"instructions": "Look up the caller's most recent order and summarize its status."
}
}{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "session is not ready; wait for session.created before sending"
}
}{
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Actually, make that a delivery instead."
}
]
}
}{
"type": "session.delegation.completed",
"delegation": {
"id": "5b1d9e02-4c77-4f3a-8a2e-1c6f0b9d7a54",
"output": "Order 40192 shipped on Tuesday and is due to arrive Thursday."
}
}First frame Telnyx sends, once the conversation is ready.
Every identifier key is always present, null where not known — a client matching on the shape does not have to distinguish "absent" from "not known yet". Keys describing a call are null for a conversation that is not a call.
Frames you send before this one are refused with an error.
Last frame Telnyx sends before closing the connection. It is not sent when the connection was already unusable — a refused peer or a peer that stopped accepting frames is closed without it.
A message was added to the conversation history — a caller utterance, an assistant reply, a tool call or a tool result.
content varies by role: a text part for ordinary messages, a tool_calls part for an assistant turn that calls tools, and a text part carrying tool_call_id for a tool result.
status is incomplete for an assistant item that is about to be streamed, and completed once it is final.
An item was removed from the conversation history, for example when an assistant turn is discarded after a barge-in.
A third party joined a multi-participant conversation.
Both human parties on a call are reported as role: "user" in the transcript, so this transition is what tells a client whose utterances start being possible. participant.id is the same identifier transcript items carry in item.participant_id.
A party left a multi-participant conversation.
The assistant started generating a response. response.id correlates every subsequent streaming frame for this turn.
An output item was opened on the response being generated. It is incomplete until the turn finishes.
A content part was opened on an output item. response.text.delta frames then fill it in.
An incremental chunk of the assistant's reply. Concatenate delta values sharing the same item_id and content_index to rebuild the text.
The underlying call was answered.
The underlying call was hung up.
The caller pressed a DTMF digit.
Answering-machine detection finished. Standard and premium detection are reported identically — which engine produced the result is not something a monitoring client should have to branch on.
A transfer out of this conversation succeeded, whether by bridging the call or by a completed SIP REFER.
Which keys are present depends on the mechanism: a bridge carries only target, while a REFER also carries the leg it was sent on and the SIP response. Keys that do not apply are omitted rather than sent as null.
A SIP REFER transfer out of this conversation failed.
The conversation was handed to a different assistant.
The socket is not re-dialled against the new assistant's websocket_settings — that would drop events across the switch — so this event is how a monitoring client learns the conversation changed hands. A handoff that cascades through several assistants is reported once, with the assistant it landed on.
The assistant is asking your server to answer a delegation. Only sent when the assistant runs delegation_settings.mode: "client".
Answer it with a session.delegation.completed frame carrying the same id. request is null for a GPT-Live delegation — the model raises one with no text of its own, and you work from the conversation events this socket is already streaming you.
If you do not answer in time, or there is no socket connected when the delegation is raised, the assistant tells the caller it cannot look things up right now and carries on.
Sent when a frame you sent is invalid or cannot be accepted right now. The connection is closed after ten consecutive invalid frames, and immediately on an oversized one. Rate-limited and refused frames are answered and discarded without counting toward that limit.
Inject a message into the conversation.
A user item triggers an answer exactly as a spoken turn does — the assistant owns turn-taking, so there is no response.create verb. An assistant item is added to the history without provoking a reply.
Only text content parts are read: input_text, output_text and text. Parts of any other type are ignored, and an item whose text is empty after trimming is rejected.
Answer a session.delegation.created frame.
Text only — this socket offers no tool vocabulary. id must be the id from the delegation being answered; an id with no delegation waiting on it resolves nothing. An output that is empty after trimming is rejected, because the assistant has already told the caller it is checking and appending nothing would be dead air.
Was this page helpful?
{
"type": "session.created",
"session": {
"conversation_id": "0c1f4a2b-6f5d-11ef-9692-02420aeffb1f",
"assistant_id": "assistant-0b9c3d21",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"call_session_id": "ff55a038-6f5d-11ef-9692-02420aeffb1f",
"call_leg_id": "428c31b6-7af4-4b6f-92e7-7a7e6a4f1d44",
"from": "+13122010094",
"to": "+13122123456",
"direction": "inbound"
}
}{
"type": "session.ended",
"reason": "normal",
"duration_sec": 84,
"transfer_status": null
}{
"type": "conversation.item.created",
"previous_item_id": "msg_5f1c0a91",
"item": {
"id": "msg_7b2e4d10",
"type": "message",
"status": "completed",
"role": "user",
"name": null,
"participant_id": "participant_1",
"content": [
{
"type": "text",
"text": "What time do you close today?"
}
]
}
}{
"type": "conversation.item.deleted",
"item_id": "msg_9c1f4a2b"
}{
"type": "conversation.participant.added",
"participant": {
"id": "participant_2",
"role": "user",
"name": "Supervisor"
}
}{
"type": "conversation.participant.removed",
"participant": {
"id": "participant_2",
"role": "user",
"name": "Supervisor"
}
}{
"type": "response.created",
"response": {
"id": "resp_9c1f4a2b",
"status": "in_progress",
"output": []
}
}{
"type": "response.output_item.added",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"item": {
"id": "msg_9c1f4a2b",
"type": "message",
"status": "incomplete",
"role": "assistant",
"name": "Support Assistant",
"content": []
}
}{
"type": "response.content_part.added",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"content_index": 0,
"item_id": "msg_9c1f4a2b",
"part": {
"type": "text",
"text": ""
}
}{
"type": "response.text.delta",
"response_id": "resp_9c1f4a2b",
"output_index": 0,
"content_index": 0,
"item_id": "msg_9c1f4a2b",
"delta": "We are open "
}{
"type": "telnyx.call.answered",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ"
}{
"type": "telnyx.call.hangup",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"cause": "normal_clearing"
}{
"type": "telnyx.call.dtmf.received",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"digit": "1"
}{
"type": "telnyx.call.machine.detection.ended",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"result": "human"
}{
"type": "telnyx.call.transfer.completed",
"target": "+13125550100"
}{
"type": "telnyx.call.transfer.failed",
"call_control_id": "v2:T02llQxIyaRkhfRKxgAP8nY511EhFLizdvdUKJiSw8d6A9BborherQ",
"target": "sip:support@example.com",
"status": "486"
}{
"type": "telnyx.assistant.handoff",
"assistant_id": "assistant-4d8e1f37"
}{
"type": "session.delegation.created",
"delegation": {
"id": "5b1d9e02-4c77-4f3a-8a2e-1c6f0b9d7a54",
"request": null,
"instructions": "Look up the caller's most recent order and summarize its status."
}
}{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "session is not ready; wait for session.created before sending"
}
}{
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Actually, make that a delivery instead."
}
]
}
}{
"type": "session.delegation.completed",
"delegation": {
"id": "5b1d9e02-4c77-4f3a-8a2e-1c6f0b9d7a54",
"output": "Order 40192 shipped on Tuesday and is due to arrive Thursday."
}
}