Core API

Participants & Joining

To connect a user to a hall, your server generates a signed join token and passes it to the frontend WebRTC client. Relay tracks each participant and records billing minutes.

Generate a join token

POST/v1/halls/:hall_id/join

Returns a short-lived signed JWT and the media server URL. Call this from your backend for each user joining the room.

Request body

participant_idstringrequired

Your stable identifier for this user (e.g. your database user ID). Used for deduplication and webhook payloads.

display_namestringrequired

Name shown to other participants in the room.

role"publisher" | "subscriber"required

publisher — can send and receive audio/video. subscriber — receive only (viewer mode).

curl
1
2
3
4
5
6
7
8
curl -X POST https://api.relay.dev/v1/halls/h_01j9x2.../join \
  -H "Authorization: Bearer relay_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "participant_id": "user_abc123",
    "display_name": "Alice",
    "role": "publisher"
  }'

Response

json
1
2
3
4
{
  "join_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "livekit_url": "wss://media.relay.dev"
}
Never call the join endpoint from your frontend. The Authorization header contains your secret API key. Always proxy through your backend.

Connect the frontend

Relay's media layer is built on LiveKit. Pass the join_token and livekit_url to the LiveKit SDK:

React
1
2
3
4
5
6
7
8
9
10
11
import { LiveKitRoom, VideoConference } from "@livekit/components-react";
import "@livekit/components-styles";

// token and serverUrl fetched from your backend
export function VideoRoom({ token, serverUrl }: { token: string; serverUrl: string }) {
  return (
    <LiveKitRoom token={token} serverUrl={serverUrl} connect video audio>
      <VideoConference />
    </LiveKitRoom>
  );
}
Install LiveKit React components
1
npm install @livekit/components-react @livekit/components-styles livekit-client

Billing & participant-minutes

Relay tracks how long each participant is connected. When a participant disconnects (or the hall is closed), the session duration is rounded up to the nearest minute and added to your billing period usage.

Example

A 45-minute standup with 6 participants = 270 participant-minutes. Starter includes 10,000/mo, Growth includes 30,000/mo. Overage is billed at $0.002/min.