-
Notifications
You must be signed in to change notification settings - Fork 1
API Reference
Complete reference for LinkUp's REST API and WebSocket endpoints.
-
Development:
http://localhost:8000 - Production: Your deployed URL
Currently, LinkUp does not require authentication. Meetings are accessible via their unique codes.
Check if the server is running.
Response:
{
"status": "healthy",
"timestamp": "2025-11-09T12:00:00Z"
}Status Codes:
-
200 OK- Server is healthy
Get server information and statistics.
Response:
{
"app": "LinkUp",
"version": "2.0",
"status": "running",
"active_meetings": 5,
"total_participants": 23
}Status Codes:
-
200 OK- Success
Create a new meeting room.
Request Body:
{
"title": "Team Standup",
"max_participants": 10
}Parameters:
-
title(string, optional) - Meeting title/description -
max_participants(integer, optional) - Maximum participants (default: 10, min: 2, max: 50)
Response:
{
"id": "uuid-here",
"code": "abc123xyz9",
"title": "Team Standup",
"created_at": "2025-11-09T12:00:00Z",
"is_active": true,
"max_participants": 10,
"participant_count": 0
}Status Codes:
-
200 OK- Meeting created successfully -
422 Unprocessable Entity- Invalid request data
Example:
curl -X POST http://localhost:8000/api/meetings \
-H "Content-Type: application/json" \
-d '{"title":"My Meeting","max_participants":5}'Retrieve information about a specific meeting.
Path Parameters:
-
meeting_code(string) - 10-character meeting code
Response:
{
"id": "uuid-here",
"code": "abc123xyz9",
"title": "Team Standup",
"created_at": "2025-11-09T12:00:00Z",
"is_active": true,
"max_participants": 10,
"participant_count": 3
}Status Codes:
-
200 OK- Meeting found -
404 Not Found- Meeting doesn't exist
Example:
curl http://localhost:8000/api/meetings/abc123xyz9List all active participants in a meeting.
Path Parameters:
-
meeting_code(string) - 10-character meeting code
Response:
[
{
"id": "uuid-here",
"client_id": "client-abc123",
"display_name": "John Doe",
"joined_at": "2025-11-09T12:00:00Z",
"is_active": true,
"is_host": true,
"audio_enabled": true,
"video_enabled": true,
"screen_sharing": false
},
{
"id": "uuid-here-2",
"client_id": "client-def456",
"display_name": "Jane Smith",
"joined_at": "2025-11-09T12:05:00Z",
"is_active": true,
"is_host": false,
"audio_enabled": true,
"video_enabled": false,
"screen_sharing": false
}
]Status Codes:
-
200 OK- Success -
404 Not Found- Meeting doesn't exist
Example:
curl http://localhost:8000/api/meetings/abc123xyz9/participantsEstablish a WebSocket connection for real-time communication.
Path Parameters:
-
meeting_code(string) - 10-character meeting code -
client_id(string) - Unique client identifier (generate on frontend)
Connection Example (JavaScript):
const ws = new WebSocket(
`ws://localhost:8000/ws/abc123xyz9/client-${Date.now()}`
);
ws.onopen = () => {
console.log('Connected to meeting');
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Received:', message);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected from meeting');
};Sent when a participant joins to set their display name.
{
"type": "join",
"displayName": "John Doe"
}Sent when a participant intentionally leaves.
{
"type": "leave"
}Send an offer to another peer to establish connection.
{
"type": "offer",
"target": "client-abc123",
"data": {
"type": "offer",
"sdp": "v=0\r\no=- ..."
}
}Respond to an offer from another peer.
{
"type": "answer",
"target": "client-abc123",
"data": {
"type": "answer",
"sdp": "v=0\r\no=- ..."
}
}Exchange ICE candidates for connection establishment.
{
"type": "ice-candidate",
"target": "client-abc123",
"data": {
"candidate": "candidate:...",
"sdpMid": "0",
"sdpMLineIndex": 0
}
}Notify others when microphone is muted/unmuted.
{
"type": "audio-toggle",
"enabled": false
}Notify others when camera is turned on/off.
{
"type": "video-toggle",
"enabled": true
}Notify others when screen sharing starts.
{
"type": "screen-share-start"
}Notify others when screen sharing stops.
{
"type": "screen-share-stop"
}Send a text message to all participants.
{
"type": "chat-message",
"message": "Hello everyone!",
"displayName": "John Doe"
}Broadcast when a new participant joins.
{
"type": "user-joined",
"clientId": "client-abc123",
"displayName": "John Doe",
"timestamp": "2025-11-09T12:00:00Z"
}Broadcast when a participant leaves.
{
"type": "user-left",
"clientId": "client-abc123",
"timestamp": "2025-11-09T12:10:00Z"
}Sent to new participants with current participant list.
{
"type": "participants-update",
"participants": ["client-abc123", "client-def456"],
"participantsData": [
{
"clientId": "client-abc123",
"displayName": "John Doe",
"audioEnabled": true,
"videoEnabled": true,
"screenSharing": false
}
]
}Forwarded between peers for WebRTC negotiation.
Offer:
{
"type": "offer",
"from": "client-abc123",
"data": {
"type": "offer",
"sdp": "v=0\r\no=- ..."
}
}Answer:
{
"type": "answer",
"from": "client-abc123",
"data": {
"type": "answer",
"sdp": "v=0\r\no=- ..."
}
}ICE Candidate:
{
"type": "ice-candidate",
"from": "client-abc123",
"data": {
"candidate": "candidate:...",
"sdpMid": "0",
"sdpMLineIndex": 0
}
}Broadcast to all when someone toggles their media.
{
"type": "audio-toggle",
"clientId": "client-abc123",
"enabled": false
}{
"type": "video-toggle",
"clientId": "client-abc123",
"enabled": true
}Broadcast when someone starts/stops screen sharing.
{
"type": "screen-share-start",
"clientId": "client-abc123"
}{
"type": "screen-share-stop",
"clientId": "client-abc123"
}Broadcast chat message to all participants.
{
"type": "chat-message",
"from": "client-abc123",
"displayName": "John Doe",
"message": "Hello everyone!",
"timestamp": "2025-11-09T12:00:00Z"
}Sent to newly joined participants with previous messages.
{
"type": "chat-history",
"messages": [
{
"from": "client-abc123",
"displayName": "John Doe",
"message": "Hello!",
"timestamp": "2025-11-09T11:55:00Z"
}
]
}Broadcast when someone updates their display name.
{
"type": "participant-name-update",
"clientId": "client-abc123",
"displayName": "John Smith"
}All API errors follow this format:
{
"detail": "Error message describing what went wrong"
}Common Status Codes:
-
400 Bad Request- Invalid request format -
404 Not Found- Resource doesn't exist -
422 Unprocessable Entity- Validation error -
500 Internal Server Error- Server error
Currently, there is no rate limiting implemented. For production deployments, consider:
- Limiting meeting creation per IP
- Throttling WebSocket messages
- Connection limits per meeting
Monitor WebSocket connection state:
const states = {
0: 'CONNECTING',
1: 'OPEN',
2: 'CLOSING',
3: 'CLOSED'
};
console.log(states[ws.readyState]);Reconnection Strategy: Implement exponential backoff for reconnection:
let reconnectDelay = 1000;
function connect() {
const ws = new WebSocket(url);
ws.onclose = () => {
setTimeout(() => {
reconnectDelay = Math.min(reconnectDelay * 2, 30000);
connect();
}, reconnectDelay);
};
ws.onopen = () => {
reconnectDelay = 1000; // Reset on successful connection
};
}Next: See WebRTC Implementation for peer-to-peer connection details.