Sessions
Persistent WebSocket endpoint for text conversations with streamed agent responses.
The Sessions API provides a persistent WebSocket for interactive text conversations. One connection carries the opening agent turn and later user turns, while each response is streamed as typed JSON frames.
For provider documentation encounters, microphone capture, and Zoom, use Scribe Sessions. Those REST routes and credentials are separate from this text WebSocket.
WebSocket routes are not represented in the HTTP OpenAPI document. This page is the public wire contract for sessions/connect.
Connect
US endpoint: wss://platform.api-us.concurrence.com/v1/{workspace_id}/sessions/connect
For Canada, Europe, or Australia, replace the host with the WebSocket form of your regional Platform endpoint.
Query Parameters
service_id
UUID
Yes
Service to run. The service must belong to the workspace.
entity_id
UUID
Yes
Person entity to bind to the conversation. The entity must belong to the workspace.
tool_events
boolean
No
Set to true to include tool-call events. The default is false; values other than true are treated as false.
context
string
No
Additional context for the opening agent turn. Only the first 5,000 characters are used.
viewport_width
integer
No
Text viewport width in characters, from 20 through 500. Invalid values are ignored.
viewport_height
integer
No
Text viewport height in characters, from 5 through 500. Invalid values are ignored. It is useful only with a valid viewport_width.
The endpoint does not use a conversation_id parameter for resumption. If supplied, it is ignored. Reconnection is based on the workspace, service_id, and entity_id instead.
Authentication
Pass two WebSocket subprotocol values:
The first value must be the literal auth. The second must be an active API key or JWT for the workspace in the URL. On an accepted connection, the server negotiates auth as the selected subprotocol.
Do not put credentials in the URL. Query-string tokens are not supported.
Connection Limits
The public contract does not define a fixed connect-rate limit, per-workspace concurrent-connection cap, or maximum connection lifetime. Infrastructure can still reject or close connections. Keep one connection per active chat, close unused sockets, and use capped exponential backoff with jitter when reconnecting.
Two operation timeouts are part of the endpoint behavior:
5 minutes waiting for an inbound text frame
Sends an idle_timeout error, then closes the WebSocket normally. The durable conversation is not closed.
60 seconds for a user turn
Sends a retryable turn_timeout error. The WebSocket remains available for a later message.
The idle timer runs while the server is waiting for the next client frame, not while an agent turn is being streamed.
Lifecycle
The client opens the WebSocket with the required query parameters and auth subprotocols.
The server validates the workspace, credential, service, and entity, then resolves an active conversation thread.
After a successful handshake, the server sends
session.created.The server immediately runs an opening agent turn and streams its events.
After that turn reaches
doneorerror, the client can send auser_textmessage.The server processes one user message at a time and streams one terminal
doneorerrorevent for that turn.Either side can close the socket. An idle timeout closes only the transport, not the durable conversation.
An open event in the browser is not proof that session validation succeeded because validation failures are delivered as WebSocket close frames. Wait for session.created before treating the session as established.
Client Messages
Send JSON objects in WebSocket text frames:
type
string
Yes
Must be user_text.
text
string
Yes
Non-empty user message, up to 10,000 characters.
Send only one user turn at a time. Wait for that turn's terminal done or error event before sending the next message. Frames that arrive while a turn is running can be buffered by the connection, but the endpoint does not provide a durable client-message queue, receipt, or idempotency key.
Binary frames and client control message types such as stop are not part of this contract. To close the durable conversation rather than only the WebSocket, use the Conversations API.
Server Frames
Every server message is a JSON text frame with an event discriminator and a data object:
Ignore any event your client does not recognize.
session.created
This is the first application frame on a successfully established session:
Store conversation_id. You can use it with the REST Conversations API to inspect the durable transcript or reconcile an ambiguous disconnect.
ping
The server sends a keepalive whenever 15 seconds pass with nothing else sent, both while a turn runs and between turns:
It keeps proxies, load balancers, and client idle watchdogs from closing a quiet connection, for example while a tool runs. It needs no reply and does not reset the 5-minute inbound idle timer, which counts only client frames. Skip it.
Turn Events
The opening turn and every user_text turn use the same event envelope:
Event
data fields
Notes
token
text
Incremental response text, in whole sentences the reply check has cleared. Use message as the authoritative completed message; it carries the correction when the check stops the reply.
tool_call_started
tool_name, call_id, input
Emitted only when tool_events=true. input is a string and can contain JSON text.
tool_call_completed
tool_name, call_id, result, succeeded, duration_ms
Emitted only when tool_events=true. result is a string; duration_ms can be null.
thinking
tier, tier_name
Reasoning-tier classification.
message
role, text
Completed agent message. A turn can emit more than one.
done
conversation_id, status, and normally turn_count, background_pending, delivery_protocol_version, turn_id, turn_index
Terminal success event. Some recovery paths provide only conversation_id and status, so clients must tolerate omitted optional fields.
error
message, code, retryable, and sometimes status_code
Terminal for the current turn. The socket normally remains open except after idle_timeout.
Do not mix this envelope with the HTTP SSE wire format. SSE uses event: and data: lines; this WebSocket sends one JSON object per text frame and removes the nested turn event discriminator from data.
Errors
client_error
Invalid JSON, unknown message type, missing or empty text, or text longer than 10,000 characters
false
upstream_error
The agent service rejected or failed the turn
true for transient statuses; otherwise false
stream_interrupted
The response stream ended because of a transport interruption
true
turn_timeout
A user turn exceeded 60 seconds
true
idle_timeout
No client text frame arrived for 5 minutes while the server was waiting
true, followed by a normal WebSocket close
The endpoint has no per-message receipt event. If the connection drops before a turn reaches done or error, the outcome is ambiguous. Read the conversation by the last conversation_id before deciding whether to retry the user's message.
Close Codes
Validation failures are accepted and then immediately closed so that clients can receive a reason code:
1000
Normal close, including the close after an idle_timeout event.
4000
Missing or malformed workspace, service_id, or entity_id.
4001
Missing, invalid, inactive, expired, or wrong-workspace credential.
4004
Workspace is missing or inactive, service is not in the workspace, or entity is not an eligible person in the workspace.
4503
The conversation thread could not be resolved before the session-creation timeout. Retry with backoff.
Other standard WebSocket close codes can still be reported for network, proxy, or unexpected server failures. Do not treat codes from a different Platform WebSocket endpoint as part of this endpoint's contract.
Reconnect and Thread Semantics
The server resolves one active WebSocket conversation thread for each (workspace_id, entity_id, service_id) combination.
Reconnecting with the same combination resumes the active durable conversation and returns the same
conversation_id.If that conversation is no longer active, including after explicit close or terminal completion, the next connection creates a new conversation and returns a new
conversation_id.Every successful connection, including a reconnect, runs an opening agent turn after
session.created.There is no event cursor, replay request, or
conversation_idquery parameter. Use the durable conversation detail endpoint to reconcile events after a disconnect.A conversation first materialized by this WebSocket can be inspected or continued over REST by using the returned
conversation_id, but a separately created REST conversation cannot be selected when opening this WebSocket.
Browser Example
This example waits for the automatic opening turn to finish before sending the first user message:
Scribe Session Guidance
Clinical session modes, lifecycle transitions, and Zoom controls have moved to Scribe Sessions. Use the Scribe deployment base and provider credentials for those operations. The following links retain the former section locations for existing bookmarks.
Session Mode
Continue with Scribe: Session Mode.
Session Lifecycle
Continue with Scribe: Session Lifecycle.
Update Session
Continue with Scribe: Update Session.
Create Session Idempotency
Continue with Scribe: Create Session Idempotency.
Conflict Error Codes
Continue with Scribe: Conflict Error Codes.
Zoom
Continue with Scribe: Zoom.
Zoom Session Lifecycle
Continue with Scribe: Zoom Session Lifecycle.
Create a Zoom Session
Continue with Scribe: Create a Zoom Session.
Pause Zoom Bot
Continue with Scribe: Pause Zoom Bot.
Resume Zoom Bot
Continue with Scribe: Resume Zoom Bot.
End Zoom Session
Continue with Scribe: End Zoom Session.
Endpoints
Continue with Scribe: Endpoints.
Authorize Response
Continue with Scribe: Authorize Response.
Connection Response
Continue with Scribe: Connection Response.
Error Handling
Continue with Scribe: Error Handling.
Last updated
Was this helpful?

