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

TypeScript
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();
StatusResponse
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

TypeScript
const ws = new WebSocket(
  'wss://radist.tech/api/v1/p2p/signaling/ws' +
    '?publicKey=<your public key>' +
    '&callToken=ct_abc123...'
);

Connection process

  1. Validate that the public key belongs to a project.
  2. Atomically consume the call token for that project.
  3. Register the socket and join the caller as a peer in the call.
  4. 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.

TypeScript
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 / CodeMessage
4400 invalid_connection_requestProvide either callToken or the full reconnect payload.
4401 unauthorizedInvalid public key.
4401 invalid_tokenInvalid or already consumed call token.

Client → server messages

TypeFieldsDescription
signaltargetPeerId, signalType, payload?Forward SDP offers, SDP answers, or ICE candidates to a connected peer.
leaverequestId?Gracefully leave the current call.

Server → client messages

TypeFieldsDescription
call_joinedcallId, peerId, reconnectToken, callThe socket joined a call with a new peer identity.
call_reconnectedcallId, peerId, callThe socket reconnected with a previous peer identity.
peer_joined | peer_reconnected | peer_leftcallId, peerId, reason?, callLifecycle updates for the other peer in the call.
call_leftcallId, peerId, reason, callConfirmation that the current socket left or disconnected.
signalcallId, fromPeerId, signalType, payload, occurredAtA WebRTC signal forwarded from the other peer.
errorcode, message, requestId?A protocol error for the connection or a specific request.

Protocol error codes

unsupported_message
socket_not_registered
already_connected
invalid_reconnect_request
call_not_found
peer_not_found
invalid_reconnect_token
peer_exists
call_full
not_connected
invalid_signal_request
target_not_found
target_unavailable

Call snapshot

Most server-to-client messages include a call object with the current in-memory signaling state.

JSON
{
  "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

TypeScript
const ws = new WebSocket(
  'wss://radist.tech/api/v1/sfu/signaling/ws' +
    '?publicKey=<your public key>' +
    '&roomToken=ct_abc123...'
);

Client → server messages

TypeFieldsDescription
connect-transporttransportId, dtlsParametersComplete the DTLS handshake for a send or recv transport.
producekind, rtpParameters, transportId?Publish an audio or video track to the room. Server replies with produced.
consumeproducerId, rtpCapabilities, transportId?Subscribe to a remote producer. Server replies with consumer-parameters.
set-preferred-layerconsumerId, spatialLayer, temporalLayer?Tune simulcast layer preferences for an existing consumer.
leave-roomLeave the current room. Closes producers/consumers and ends billing.
e2ee-announcepublicKey, keyIdBroadcast your X25519 public key and current sender key ID to all peers in the room.
e2ee-keytargetPeerId, keyId, wrappedKey, wrapIvDeliver an ECDH-wrapped sender key to a specific peer.
e2ee-request-keytargetPeerIdAsk a specific peer to resend their latest wrapped sender key.

Server → client messages

TypeFieldsDescription
room-joinedroomId, peerId, sendTransport, recvTransport, existingPeersInitial snapshot with transport parameters and currently connected peers.
transport-connectedtransportIdAcknowledges a successful connect-transport request.
producedproducerId, kindAcknowledges a produce request and assigns a producer id.
new-producerpeerId, producerId, kindAnother peer started producing. Call consume to subscribe.
consumer-parameterspeerId, consumerId, producerId, kind, rtpParametersReply to a consume request with the rtpParameters needed by mediasoup-client.
peer-leftpeerIdA peer disconnected or left the room.
errorcode?, messageA protocol error for the connection or last request.
e2ee-peer-announcedfromPeerId, publicKey, keyIdA peer broadcast their X25519 public key and sender key ID.
e2ee-peer-keyfromPeerId, keyId, wrappedKey, wrapIvA peer delivered their wrapped sender key to you.
e2ee-key-requestedfromPeerIdA peer is requesting that you resend your latest wrapped sender key.