For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

This page covers conversation sessions. It is unrelated to the login and token sessions documented under Authentication & API Keys.

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

Parameter
Type
Required
Description

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:

Timeout
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

  1. The client opens the WebSocket with the required query parameters and auth subprotocols.

  2. The server validates the workspace, credential, service, and entity, then resolves an active conversation thread.

  3. After a successful handshake, the server sends session.created.

  4. The server immediately runs an opening agent turn and streams its events.

  5. After that turn reaches done or error, the client can send a user_text message.

  6. The server processes one user message at a time and streams one terminal done or error event for that turn.

  7. 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:

Field
Type
Required
Description

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

Code
Meaning
Retryable value

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:

Code
Reason

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_id query 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

Update Session

Continue with Scribe: Update Session.

Create Session Idempotency

Conflict Error Codes

Zoom

Continue with Scribe: Zoom.

Zoom Session Lifecycle

Create a Zoom Session

Pause Zoom Bot

Continue with Scribe: Pause Zoom Bot.

Resume Zoom Bot

End Zoom Session

Endpoints

Continue with Scribe: Endpoints.

Authorize Response

Connection Response

Error Handling

Continue with Scribe: Error Handling.

Last updated

Was this helpful?