Skip to content

API Reference

Martian edited this page Nov 9, 2025 · 1 revision

API Reference

Complete reference for LinkUp's REST API and WebSocket endpoints.

Base URL

  • Development: http://localhost:8000
  • Production: Your deployed URL

Authentication

Currently, LinkUp does not require authentication. Meetings are accessible via their unique codes.


REST API Endpoints

Health Check

GET /health

Check if the server is running.

Response:

{
  "status": "healthy",
  "timestamp": "2025-11-09T12:00:00Z"
}

Status Codes:

  • 200 OK - Server is healthy

Root Endpoint

GET /

Get server information and statistics.

Response:

{
  "app": "LinkUp",
  "version": "2.0",
  "status": "running",
  "active_meetings": 5,
  "total_participants": 23
}

Status Codes:

  • 200 OK - Success

Meeting Endpoints

Create Meeting

POST /api/meetings

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}'

Get Meeting Details

GET /api/meetings/{meeting_code}

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/abc123xyz9

Get Meeting Participants

GET /api/meetings/{meeting_code}/participants

List 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/participants

WebSocket API

Connection

WS /ws/{meeting_code}/{client_id}

Establish 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');
};

WebSocket Message Types

Client → Server Messages

Join Meeting

Sent when a participant joins to set their display name.

{
  "type": "join",
  "displayName": "John Doe"
}

Leave Meeting

Sent when a participant intentionally leaves.

{
  "type": "leave"
}

WebRTC Offer

Send an offer to another peer to establish connection.

{
  "type": "offer",
  "target": "client-abc123",
  "data": {
    "type": "offer",
    "sdp": "v=0\r\no=- ..."
  }
}

WebRTC Answer

Respond to an offer from another peer.

{
  "type": "answer",
  "target": "client-abc123",
  "data": {
    "type": "answer",
    "sdp": "v=0\r\no=- ..."
  }
}

ICE Candidate

Exchange ICE candidates for connection establishment.

{
  "type": "ice-candidate",
  "target": "client-abc123",
  "data": {
    "candidate": "candidate:...",
    "sdpMid": "0",
    "sdpMLineIndex": 0
  }
}

Audio Toggle

Notify others when microphone is muted/unmuted.

{
  "type": "audio-toggle",
  "enabled": false
}

Video Toggle

Notify others when camera is turned on/off.

{
  "type": "video-toggle",
  "enabled": true
}

Screen Share Start

Notify others when screen sharing starts.

{
  "type": "screen-share-start"
}

Screen Share Stop

Notify others when screen sharing stops.

{
  "type": "screen-share-stop"
}

Chat Message

Send a text message to all participants.

{
  "type": "chat-message",
  "message": "Hello everyone!",
  "displayName": "John Doe"
}

Server → Client Messages

User Joined

Broadcast when a new participant joins.

{
  "type": "user-joined",
  "clientId": "client-abc123",
  "displayName": "John Doe",
  "timestamp": "2025-11-09T12:00:00Z"
}

User Left

Broadcast when a participant leaves.

{
  "type": "user-left",
  "clientId": "client-abc123",
  "timestamp": "2025-11-09T12:10:00Z"
}

Participants Update

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
    }
  ]
}

WebRTC Signaling Messages

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
  }
}

Audio/Video Toggle

Broadcast to all when someone toggles their media.

{
  "type": "audio-toggle",
  "clientId": "client-abc123",
  "enabled": false
}
{
  "type": "video-toggle",
  "clientId": "client-abc123",
  "enabled": true
}

Screen Share Events

Broadcast when someone starts/stops screen sharing.

{
  "type": "screen-share-start",
  "clientId": "client-abc123"
}
{
  "type": "screen-share-stop",
  "clientId": "client-abc123"
}

Chat Message

Broadcast chat message to all participants.

{
  "type": "chat-message",
  "from": "client-abc123",
  "displayName": "John Doe",
  "message": "Hello everyone!",
  "timestamp": "2025-11-09T12:00:00Z"
}

Chat History

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"
    }
  ]
}

Participant Name Update

Broadcast when someone updates their display name.

{
  "type": "participant-name-update",
  "clientId": "client-abc123",
  "displayName": "John Smith"
}

Error Responses

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

Rate Limiting

Currently, there is no rate limiting implemented. For production deployments, consider:

  • Limiting meeting creation per IP
  • Throttling WebSocket messages
  • Connection limits per meeting

WebSocket Connection States

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.