Documentation
Embed the media stack, wire up webhooks, and get the network requirements past your IT department.
Web SDK
One import, one token, one container element.
js
import { joinRoom } from '@roundtable/web';
const room = await joinRoom({
token, // minted server-side
container: '#call',
video: { simulcast: true, maxBitrate: 1_700_000 },
audio: { noiseSuppression: true }
});
room.on('participant-joined', p => console.log(p.identity));Tokens
Tokens are JWTs signed with your API secret. Mint them on your server, never in the browser, and keep the lifetime short.
json
{
"room": "design-review-tuesday",
"identity": "alex@company.example",
"grants": {"publish": true, "subscribe": true,
"recordingAdmin": false},
"exp": 1786000000
}Network requirements
| Protocol | Destination | Ports | Notes |
|---|---|---|---|
| UDP | media regions | 10000–20000 | preferred path |
| TCP | media regions | 443 | fallback when UDP is blocked |
| TLS | api.roundtable.works | 443 | signalling |
| TURN | turn.roundtable.works | 443 | last resort relay |
If UDP is blocked, calls still work over TCP/443, but expect latency to roughly double and packet-loss recovery to be less graceful. It is worth the firewall ticket.
Webhooks
room.startedroom.finishedparticipant.joinedparticipant.leftrecording.readytranscript.ready
Recordings
Composited MP4 by default, or individual tracks if you want to edit. Delivered to our storage or straight to your bucket.
bash
curl -X POST https://api.roundtable.works/v1/recordings \
-H "Authorization: Bearer $RT_KEY" \
-d '{"room":"design-review-tuesday",
"layout":"speaker",
"output":{"s3":{"bucket":"rec.company.example"}}}'