Client SDK
HTTP & WebSocket API
Lower-level P2P token minting and the signaling WebSocket protocol. Use @radist-tech/client to skip this and work at a higher level. Call creation requires a secret key — see the Server SDK API reference.
HTTP API
All endpoints live under /api/v1. All responses are JSON. These endpoints accept a rad_pk_... public key.
POST /api/v1/p2p/calls/:callId/token
Mints another participant token for an existing call. Authenticated with Authorization: Bearer rad_pk_....
const response = await fetch(
`https://radist.tech/api/v1/p2p/calls/${callId}/token`,
{
method: 'POST',
headers: {
Authorization: 'Bearer <your public key>'
}
}
);
const { callToken } = await response.json();| Status | Response |
|---|---|
| 200 | { "callToken": "ct_..." } |
| 401 | { "error": "Missing bearer token." } or invalid public key |
| 404 | { "error": "Call not found." } |
| 409 | { "error": "All peers are already connected." } |
| 410 | { "error": "Call has been terminated." } |
WebSocket API
Custom clients connect to the signaling WebSocket with a public key and either a fresh call token or a full reconnect payload. The browser SDK manages this protocol automatically.
Initial connection
const ws = new WebSocket(
'wss://radist.tech/api/v1/p2p/signaling/ws' +
'?publicKey=<your public key>' +
'&callToken=ct_abc123...'
);Connection process
- Validate that the public key belongs to a project.
- Atomically consume the call token for that project.
- Register the socket and join the caller as a peer in the call.
- Return a peer ID, reconnect token, and current call snapshot.
Reconnect
Reconnect by opening a new socket with the public key, call ID, previous peer ID, and
reconnect token. This is what connection.reconnect() wraps in the browser SDK.
const ws = new WebSocket(
'wss://radist.tech/api/v1/p2p/signaling/ws' +
'?publicKey=<your public key>' +
'&callId=550e8400-e29b-41d4-a716-446655440000' +
'&peerId=peer_a1b2c3' +
'&reconnectToken=rt_abc123...'
);Connection errors
| Close / Code | Message |
|---|---|
| 4400 invalid_connection_request | Provide either callToken or the full reconnect payload. |
| 4401 unauthorized | Invalid public key. |
| 4401 invalid_token | Invalid or already consumed call token. |
Client → server messages
| Type | Fields | Description |
|---|---|---|
| signal | targetPeerId, signalType, payload? | Forward SDP offers, SDP answers, or ICE candidates to a connected peer. |
| leave | requestId? | Gracefully leave the current call. |
Server → client messages
| Type | Fields | Description |
|---|---|---|
| call_joined | callId, peerId, reconnectToken, call | The socket joined a call with a new peer identity. |
| call_reconnected | callId, peerId, call | The socket reconnected with a previous peer identity. |
| peer_joined | peer_reconnected | peer_left | callId, peerId, reason?, call | Lifecycle updates for the other peer in the call. |
| call_left | callId, peerId, reason, call | Confirmation that the current socket left or disconnected. |
| signal | callId, fromPeerId, signalType, payload, occurredAt | A WebRTC signal forwarded from the other peer. |
| error | code, message, requestId? | A protocol error for the connection or a specific request. |
Protocol error codes
Call snapshot
Most server-to-client messages include a call object with the current in-memory signaling state.
{
"callId": "550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2026-05-05T10:30:00.000Z",
"updatedAt": "2026-05-05T10:31:00.000Z",
"peers": [
{ "peerId": "peer_a1b2c3", "status": "connected", "updatedAt": "..." },
{ "peerId": "peer_d4e5f6", "status": "disconnected", "updatedAt": "..." }
]
}Room WebSocket API
Connect to the room signaling endpoint with the project public key and one fresh room token.
The server replies with a room-joined message containing transport parameters and
the list of peers already in the room. Room tokens are minted from your backend — see the Server SDK API reference.
Plug the returned transport parameters into mediasoup-client to handle the actual media plane.
Connect
const ws = new WebSocket(
'wss://radist.tech/api/v1/sfu/signaling/ws' +
'?publicKey=<your public key>' +
'&roomToken=ct_abc123...'
);Client → server messages
| Type | Fields | Description |
|---|---|---|
| connect-transport | transportId, dtlsParameters | Complete the DTLS handshake for a send or recv transport. |
| produce | kind, rtpParameters, transportId? | Publish an audio or video track to the room. Server replies with produced. |
| consume | producerId, rtpCapabilities, transportId? | Subscribe to a remote producer. Server replies with consumer-parameters. |
| set-preferred-layer | consumerId, spatialLayer, temporalLayer? | Tune simulcast layer preferences for an existing consumer. |
| leave-room | — | Leave the current room. Closes producers/consumers and ends billing. |
| e2ee-announce | publicKey, keyId | Broadcast your X25519 public key and current sender key ID to all peers in the room. |
| e2ee-key | targetPeerId, keyId, wrappedKey, wrapIv | Deliver an ECDH-wrapped sender key to a specific peer. |
| e2ee-request-key | targetPeerId | Ask a specific peer to resend their latest wrapped sender key. |
Server → client messages
| Type | Fields | Description |
|---|---|---|
| room-joined | roomId, peerId, sendTransport, recvTransport, existingPeers | Initial snapshot with transport parameters and currently connected peers. |
| transport-connected | transportId | Acknowledges a successful connect-transport request. |
| produced | producerId, kind | Acknowledges a produce request and assigns a producer id. |
| new-producer | peerId, producerId, kind | Another peer started producing. Call consume to subscribe. |
| consumer-parameters | peerId, consumerId, producerId, kind, rtpParameters | Reply to a consume request with the rtpParameters needed by mediasoup-client. |
| peer-left | peerId | A peer disconnected or left the room. |
| error | code?, message | A protocol error for the connection or last request. |
| e2ee-peer-announced | fromPeerId, publicKey, keyId | A peer broadcast their X25519 public key and sender key ID. |
| e2ee-peer-key | fromPeerId, keyId, wrappedKey, wrapIv | A peer delivered their wrapped sender key to you. |
| e2ee-key-requested | fromPeerId | A peer is requesting that you resend your latest wrapped sender key. |