WebSocket signaling
The signaling channel is a WebSocket connection used to exchange SDP offers/answers and ICE candidates between your client and the WebRTC Gateway.
Endpoint
Message format
All messages are JSON objects with a common top-level structure.
Message type. One of offer, answer, ice-candidate, error, close.
Session identifier. Send an empty string ("") when creating a new session with an offer.
Message-specific payload. Structure depends on the message type.
Authentication token. Required in every offer message, including studio draft and preview calls. Offers without a valid authToken are rejected with an UNAUTHORIZED error (Auth token required). Setting agentVersionOverride, accountId, or projectId does not exempt a call from authentication.
The gateway accepts two token types:
- Connector token — the same token used on your project’s SIP connector (the
X-PolyAi-Auth-Tokenvalue provided by PolyAI). Use this for any client outside Agent Studio. It is durable across redeploys. - Studio-minted JWT — issued automatically by Agent Studio for in-Studio calls. It goes stale on redeploy and is not suitable for external integrations.
For widgets, native apps, and custom WebRTC clients, use the connector token.
Agent mode for the session. Defaults to end-to-end when omitted.
Unknown values are rejected with an INVALID_ARGUMENT error. Legacy values (agent, agent_v1, agent_v2, cascaded, normal, realtime) are still accepted but resolve to a canonical value and may be removed in a future release. Update integrations to use the canonical names.
Echo mode is restricted to debug environments. Echo mode (mode: "echo") loops your audio back to the client and is intended for connectivity testing. Production gateways reject echo offers with a FORBIDDEN error before any session is created. Use agent mode (the default) for normal voice agent traffic.
Unique call identifier (camelCase – this is distinct from the Outbound Calling API’s call_sid field).
Calling number.
Called number.
Account identifier.
Project identifier.
Optional variant override.
Optional pinning of a specific agent build. Both fields are required when set:
artifactVersion(string)lambdaDeploymentVersion(string)
Setting agentVersionOverride does not bypass authentication. A valid authToken is still required.
Operations
Send offer
Direction: client to server
Starts a new session. Send with an empty sessionId and include your authToken.
The data field contains the SDP offer:
Must be "offer".
Full SDP string from your local peer connection.
Receive answer
Direction: server to client
Sent by the server in response to a valid offer. Contains the SDP answer and the assigned sessionId. Store the sessionId and use it for all subsequent messages.
The data field contains the SDP answer:
Must be "answer".
Full SDP string from the server.
Exchange ICE candidates
Direction: bidirectional
Sent by both client and server to exchange network connectivity candidates. Continue exchanging until the WebRTC connection is established.
The data field contains the ICE candidate:
ICE candidate string.
Media stream identification tag.
Zero-based index of the media description in the SDP.
Close
Direction: client to server
Terminates the session gracefully. Send when you want to end the call.
Error
Direction: server to client
Sent when the server encounters an error during the session.
The data field contains the error details:
Error code identifying the failure type.
Human-readable error description.
Error codes
Connection flow
Send offer
Create a local RTCPeerConnection, add your microphone track, generate an SDP offer, and send it with your authToken.
Receive answer
The server responds with an SDP answer and a sessionId. Set the remote description on your peer connection.
Exchange ICE candidates
Forward ICE candidates from your onicecandidate handler. Add incoming candidates from the server to your peer connection.

