Skip to content

Latest commit

 

History

History
183 lines (120 loc) · 5.79 KB

File metadata and controls

183 lines (120 loc) · 5.79 KB

API Reference

REST API for VideoCircle. All endpoints are versioned under /api/v1.

  • Base URL (local): http://localhost:8000
  • Base URL (demo): the deployed backend URL (e.g. https://videocircle-backend.onrender.com)
  • Content type: application/json. Request bodies are capped at 40 KB.
  • CORS: open to all origins.

Authentication

Two independent schemes — see ARCHITECTURE.md for the full rationale.

Scheme Used by How
App auth /api/v1/users/* protected routes Authorization: Bearer <token> where <token> is the opaque 40-char session token returned by Google sign-in (POST /api/v1/users/google). Not a JWT. 7-day TTL.
LiveKit auth /api/v1/meet/get-token None. The endpoint is public; it issues a LiveKit JWT for the browser to connect to LiveKit Cloud.

Rate limiting

Every route is rate-limited to 100 requests per 15 minutes, per IP. Each route has its own named limiter so caps can diverge later, but they share one config today. Standard RateLimit-* headers are returned; the legacy X-RateLimit-* headers are disabled. Over the limit returns 429.

Error format

Every error response has the shape:

{ "status": 400, "message": "Human-readable reason" }

Validation failures (Zod) additionally include an issues array:

{
  "status": 400,
  "message": "Validation failed",
  "issues": [{ "path": "body.accessToken", "message": "accessToken is required" }]
}

Unknown routes return 404 via the notFoundHandler.


Health

GET /api/v1/healthz

Public. Used for uptime checks. Takes no parameters.

200 OK

{ "ok": true }

Users — /api/v1/users

POST /google

Public. Sign-in is Google-only — there is no username/password. The browser uses Google's OAuth popup flow (useGoogleLogin from @react-oauth/google) and posts the resulting access token here. The backend validates it with google-auth-library (getTokenInfo, asserting the token's audience equals GOOGLE_CLIENT_ID), fetches the profile from Google's /userinfo endpoint, upserts the user by their Google sub, and returns a fresh session token. Each sign-in rotates the token — one active session per user.

Request body

Field Type Rules
accessToken string required, non-empty — the Google OAuth access token
{ "accessToken": "ya29.a0Af…" }

200 OK

{ "token": "9f2c…<40 hex chars>" }

Errors401 "Invalid Google access token" if introspection fails; 401 "Google token was not issued for this app" on audience mismatch; 401 "Could not fetch Google profile" if the userinfo request fails; 401 "Google account email is not verified" if Google reports the email as unverified; 400 on validation failure.

GET /verify

Auth required (Bearer). Validates the current session token and echoes back the user's public profile. Expired tokens are cleared server-side and rejected.

200 OK

{ "message": "Valid", "user": { "name": "Ada Lovelace", "email": "ada@example.com" } }

Errors401 if the token is missing, invalid, or expired.

POST /add_to_activity

Auth required (Bearer). Appends a meeting to the authenticated user's history. The history record is keyed by the caller's user id (resolved from the token), so the body only carries the code.

Request body

Field Type Rules
meetingCode string required, non-empty (trimmed)
{ "meetingCode": "stand-up-42" }

201 Created

{ "message": "Added code to history" }

Errors401 if unauthenticated; 400 on validation failure.

GET /get_all_activity

Auth required (Bearer). Returns every meeting logged for the current user.

200 OK — an array of meeting records:

[
  {
    "_id": "665f…",
    "user_id": "664a…",
    "meetingCode": "stand-up-42",
    "date": "2026-06-02T10:15:00.000Z"
  }
]

user_id holds the user's Mongo _id as a string (not an ObjectId ref).

Errors401 if unauthenticated.


Meet — /api/v1/meet

GET /get-token

Public. Issues a short-lived LiveKit access token so the browser can connect directly to LiveKit Cloud. There is no app-auth on this endpoint — meeting codes are the only access control.

Query parameters

Param Type Rules
room string required, non-empty (trimmed) — the meeting code
username string required, non-empty (trimmed) — display name
GET /api/v1/meet/get-token?room=stand-up-42&username=Ada

200 OK

{
  "token": "<LiveKit JWT>",
  "url": "wss://your-project.livekit.cloud"
}

The JWT carries a 1-hour TTL and the grants roomJoin, canPublish, and canSubscribe (no roomCreate — LiveKit auto-creates the room on first join). The token identity is ${username}-${randomUUID} (the UUID suffix prevents two same-named callers from colliding into one LiveKit participant); name is the raw username, used for chat display.

url is the backend's LIVEKIT_URL. The frontend connects using its own REACT_APP_LIVEKIT_URL — both must point at the same project. See LIVEKIT_SETUP.md.

Errors400 if room or username is missing/empty.


Quick reference

Method Endpoint Auth Success
GET /api/v1/healthz Public 200
POST /api/v1/users/google Public 200
GET /api/v1/users/verify Bearer 200
POST /api/v1/users/add_to_activity Bearer 201
GET /api/v1/users/get_all_activity Bearer 200
GET /api/v1/meet/get-token Public 200