Server SDK
HTTP & WebSocket API
Raw HTTP endpoints for managing P2P calls and rooms. All endpoints here accept a secret key
(rad_sk_...) and must only be called from your backend.
Overview
Calls with more than two participants use rooms. Create a room from your backend, mint one room token per participant, and each participant connects to the room signaling WebSocket. Audio and video are forwarded through a mediasoup worker.
Billing
Every second each participant is connected to a room is reported to Stripe as radist_sfu_participant_seconds.
The 30-day total is visible on the project billing page.
HTTP API
P2P calls
POST /api/v1/projects/:projectId/calls
Creates a call and auto-mints two participant tokens. Authenticated with Authorization: Bearer rad_sk_... and the project id path parameter.
const projectId = '<your project id>';
const response = await fetch(`https://radist.tech/api/v1/projects/${projectId}/calls`, {
method: 'POST',
headers: {
Authorization: 'Bearer <your secret key>'
}
});
const { callId, callTokens } = await response.json();
const [hostCallToken, guestCallToken] = callTokens;| Status | Response |
|---|---|
| 200 | { "callId": "uuid", "callTokens": ["ct_...", "ct_..."] } |
| 401 | { "error": "Missing bearer token." } or invalid project id/key |
| 429 | { "error": "Connection limit reached." } |
GET /api/v1/projects/:projectId/calls
Lists calls for the project. Query parameters: page (default 1) and limit (default 20, max 100).
const projectId = '<your project id>';
const response = await fetch(
`https://radist.tech/api/v1/projects/${projectId}/calls?page=1&limit=20`,
{
headers: { Authorization: 'Bearer <your secret key>' }
}
);
const page = await response.json();
// { calls: [{ callId, createdAt, tombstonedAt }], page, limit, total }| Status | Response |
|---|---|
| 200 | { "calls": [...], "page": 1, "limit": 20, "total": 42 } |
| 400 | { "error": "Invalid page query parameter." } |
| 401 | { "error": "Missing bearer token." } or invalid project id/key |
Call lifecycle
- Each P2P call starts with two pending tokens from POST /api/v1/projects/:projectId/calls.
- Additional tokens can be minted by the client with the public-key endpoint.
- Pending tokens are consumed once and cleared after both peers are connected.
- A call is tombstoned after all peers disconnect.
SFU rooms
POST /api/v1/projects/:projectId/rooms
Creates a room and auto-mints two room tokens. Authenticated with Authorization: Bearer rad_sk_... and the project id path parameter.
const projectId = '<your project id>';
const response = await fetch(
`https://radist.tech/api/v1/projects/${projectId}/rooms`,
{
method: 'POST',
headers: { Authorization: 'Bearer <your secret key>' }
}
);
const { roomId, roomTokens } = await response.json();POST /api/v1/projects/:projectId/rooms/:roomId/token
Mints an additional room token for an existing room. Authenticated with Authorization: Bearer rad_sk_....
const projectId = '<your project id>';
const response = await fetch(
`https://radist.tech/api/v1/projects/${projectId}/rooms/${roomId}/token`,
{
method: 'POST',
headers: { Authorization: 'Bearer <your secret key>' }
}
);
const { roomToken } = await response.json();SFU WebSocket signaling
Participants connect to the SFU signaling WebSocket directly using a public key and room token. See the Client SDK API reference for the full protocol.