Download OpenAPI specification:
These are the API endpoints for all PeerPrep microservices
Returns the currently authenticated user's information.
The user is identified by decoding the JWT access token from the jwt_access_token cookie.
{- "id": "a1b2c3d4e5",
- "username": "johndoe",
- "email": "johndoe@example.com",
- "isAdmin": false,
- "createdAt": "2025-11-04T15:23:00.000Z",
- "updatedAt": "2025-11-04T15:23:00.000Z"
}Retrieves a user's profile information by their unique ID. Requires authentication via cookies.
| id required | string The ID of the user to retrieve. |
{- "id": "a1b2c3d4e5",
- "username": "johndoe",
- "email": "johndoe@example.com",
- "isAdmin": false,
- "createdAt": "2025-11-04T15:23:00.000Z",
- "updatedAt": "2025-11-04T15:23:00.000Z"
}Updates user information (username, email, or password). At least one field must be updated.
Requires the user's current password for verification.
Only the authenticated user can update their own account, authorized via request cookies.
| id required | string The ID of the user to update. |
| currentPassword | string <password> The user's current password (required). |
| newPassword | string <password> The new password (min. 3 characters). |
| newEmail | string <email> The new email address. |
| newUsername | string The new username. |
{- "currentPassword": "oldPass123",
- "newPassword": "newPass456",
- "newEmail": "newmail@example.com",
- "newUsername": "newusername"
}{- "id": "a1b2c3d4e5",
- "username": "newusername",
- "email": "newmail@example.com",
- "isAdmin": false
}Creates a new user account after validating input and ensuring the username and email are unique.
| username required | string >= 3 characters The desired username. Must be at least 3 characters long. |
| email required | string <email> >= 3 characters The user's email address. |
| password required | string <password> >= 3 characters The user's password. Must be at least 3 characters long. |
{- "username": "johndoe",
- "email": "johndoe@example.com",
- "password": "mySecureP@ssw0rd"
}{- "id": "f1a2b3c4d5",
- "username": "johndoe",
- "email": "johndoe@example.com",
- "isAdmin": false,
- "createdAt": "2025-11-04T15:23:00.000Z",
- "updatedAt": "2025-11-04T15:23:00.000Z"
}Authenticates a user with email and password. Returns user info and sets access and refresh tokens in cookies.
| email required | string <email> The email address associated with the user account. |
| password required | string <password> The user's password. |
{- "email": "johndoe@example.com",
- "password": "mySecureP@ssw0rd"
}{- "id": "a1b2c3d4e5",
- "username": "johndoe",
- "email": "johndoe@example.com",
- "isAdmin": false,
- "createdAt": "2025-11-04T15:23:00.000Z",
- "updatedAt": "2025-11-04T15:23:00.000Z"
}Logs out the currently authenticated user by removing the stored refresh token
and clearing authentication cookies (jwt_access_token and jwt_refresh_token).
This endpoint requires that the user is currently logged in.
{- "message": "User logged out"
}Generates a new access token using a valid refresh token stored in the jwt_refresh_token cookie.
The new access token is set as an HTTP-only cookie (jwt_access_token).
{- "message": "Access token refreshed"
}Creates a new attempt for a given collaboration and question.
Requires authentication via the jwt_access_token cookie.
| collabId required | string |
| questionId required | number |
| content required | string |
{- "collabId": "d5ed2f3b-942c-4543-a0d3-a6f57f4bf2b4",
- "questionId": 42,
- "content": "function add(a, b) { return a + b; }"
}{- "message": "Attempt created"
}Retrieves all attempts made by a specific user.
| id required | string Example: d5ed2f3b-942c-4543-a0d3-a6f57f4bf2b4 The user's unique ID. |
[- {
- "id": "456",
- "userId": "d06a435b-be8f-4643-a53c-49c9e073aa35",
- "collabId": "d5ed2f3b-942c-4543-a0d3-a6f57f4bf2b4",
- "questionId": 42,
- "content": "function add(a, b) { return a + b; }",
- "createdAt": "2025-11-04T15:23:00.000Z"
}, - {
- "id": "789",
- "userId": "d06a435b-be8f-4643-a53c-49c9e073aa35",
- "collabId": "d5ed2f3b-942c-4543-a0d3-a6f57f4bf2b4",
- "questionId": 7,
- "content": "def multiply(a, b): return a * b",
- "createdAt": "2025-11-05T10:10:00.000Z"
}
]Retrieves a list of questions with optional filters and pagination.
| search | string Example: search=binary search Search by question title or statement. |
| topicNames | string Example: topicNames=Arrays,Sorting Comma-separated topic names to filter by. |
| difficulty | string Example: difficulty=Easy,Medium Filter by difficulty (single or comma-separated values). |
| orderBy | string Enum: "newest" "oldest" "title" Example: orderBy=newest Sort order of results. |
| skip | integer Example: skip=0 Number of results to skip. |
| take | integer Example: take=25 Maximum number of results to return. |
[- {
- "id": 1,
- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2,7,11,15], 9",
- "output": "[0,1]"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map.",
- "createdAt": "2025-11-01T12:00:00Z"
}, - {
- "id": 2,
- "title": "Merge Intervals",
- "statement": "Merge overlapping intervals.",
- "difficulty": "Medium",
- "topicNames": [
- "Sorting",
- "Intervals"
], - "exampleIO": [
- {
- "input": "[[1,3],[2,6],[8,10]]",
- "output": "[[1,6],[8,10]]"
}
], - "constraints": [
- "0 <= intervals.length <= 10^4"
], - "solutionOutline": "Sort and merge adjacent overlaps.",
- "createdAt": "2025-11-02T10:00:00Z"
}
]Create a new question with metadata, examples, and topics.
| title required | string |
| statement required | string |
| difficulty required | string Enum: "Easy" "Medium" "Hard" |
| topicNames | Array of strings |
Array of objects (ExampleIO) | |
| constraints | Array of strings |
| solutionOutline required | string |
| metadata | object or null |
{- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2, 3]",
- "output": "5"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map.",
- "metadata": {
- "source": "LeetCode",
- "id": 1
}
}{- "id": 1,
- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2, 3]",
- "output": "5"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map to track complements.",
- "metadata": {
- "source": "LeetCode",
- "id": 1
}, - "createdAt": "2025-11-01T12:00:00Z"
}Retrieve a specific question by its numeric ID.
| id required | integer Example: 1 |
{- "id": 1,
- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2, 3]",
- "output": "5"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map to track complements.",
- "metadata": {
- "source": "LeetCode",
- "id": 1
}, - "createdAt": "2025-11-01T12:00:00Z"
}Updates fields of an existing question. If the question is marked as deleted, this performs a soft delete.
| id required | integer Example: 1 |
| title required | string |
| statement required | string |
| difficulty required | string Enum: "Easy" "Medium" "Hard" |
| topicNames | Array of strings |
Array of objects (ExampleIO) | |
| constraints | Array of strings |
| solutionOutline required | string |
| metadata | object or null |
{- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2, 3]",
- "output": "5"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map.",
- "metadata": {
- "source": "LeetCode",
- "id": 1
}
}{- "id": 1,
- "title": "Two Sum",
- "statement": "Find two numbers that add up to target.",
- "difficulty": "Easy",
- "topicNames": [
- "Arrays",
- "Hash Map"
], - "exampleIO": [
- {
- "input": "[2, 3]",
- "output": "5"
}
], - "constraints": [
- "2 <= nums.length <= 10^4"
], - "solutionOutline": "Use a hash map to track complements.",
- "metadata": {
- "source": "LeetCode",
- "id": 1
}, - "createdAt": "2025-11-01T12:00:00Z"
}Queues the user for a match or immediately returns a matched session if found. Requires user authentication.
| userId | string |
string or Array of strings | |
string or Array of strings | |
string or Array of strings | |
| ttlMs | integer Time (ms) before the match request expires. |
{- "userId": "user123",
- "languageIn": "JavaScript",
- "difficultyIn": "Easy",
- "topicIn": "Algorithms",
- "ttlMs": 300000
}{- "status": "matched",
- "roomId": "room789",
- "topic": "Graphs",
- "difficulty": "Medium",
- "language": "Python",
- "questionId": 42,
- "userId": "user123",
- "partnerId": "user456",
- "session": {
- "id": "room789",
- "topic": "Graphs",
- "difficulty": "Medium",
- "questionId": 42,
- "status": "ACTIVE",
- "expiresAt": "2025-11-06T12:00:00.000Z",
- "participants": [
- {
- "userId": "user123"
}, - {
- "userId": "user456"
}
]
}
}Returns the current matchmaking status (QUEUED, MATCHED, CANCELLED, or EXPIRED) for the given user.
| userId required | string Example: user123 |
{- "userId": "user123",
- "status": "QUEUED",
- "position": 2
}Cancels a matchmaking request for the given user.
| userId | string |
{- "userId": "user123"
}{- "userId": "user123",
- "status": "CANCELLED"
}Opens a Server-Sent Events (SSE) stream for real-time matchmaking updates. The stream sends the following events:
heartbeat: every 15sMATCH_FOUND: when a match is foundTIMEOUT: if no match found before ttlMs expires| userId required | string Example: user123 |
| ttlMs | integer Example: ttlMs=30000 |
| pollMs | integer Example: pollMs=1000 |
event: heartbeat data: {} event: MATCH_FOUND data: {"roomId":"room789","topic":"Graphs","difficulty":"Medium"}
Triggers a match notification for the given user, typically used internally by the system.
| userId required | string Example: user123 |
| roomId | string |
{- "roomId": "room789"
}{- "ok": true,
- "delivered": 1,
- "userId": "user123",
- "roomId": "room789"
}Retrieves a user's currently active session by the jwt_access_token in the request cookies.
{- "data": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
}Retrieves a user's currently active session by his username.
| username required | string <email> |
{- "username": "johndoe"
}{- "data": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
}Creates a new collab session for 2 users after a successful match.
| topic required | string |
| difficulty required | string |
| questionId required | string |
| id | string |
| expiresAt | string <date-time> |
| user1ID | string |
| user2ID | string |
| language required | string Enum: "java" "python" |
{- "topic": "string",
- "difficulty": "string",
- "questionId": "string",
- "id": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "user1ID": "string",
- "user2ID": "string",
- "language": "java"
}{- "data": {
- "fresh": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z",
- "participants": [
- {
- "username": "alice",
- "id": "part1",
- "sessionId": "abc123",
- "userId": "user1",
- "joinedAt": "2025-11-07T14:05:00Z",
- "leftAt": null
}, - {
- "username": "bob",
- "id": "part2",
- "sessionId": "abc123",
- "userId": "user2",
- "joinedAt": "2025-11-07T14:10:00Z",
- "leftAt": null
}
]
}
}
}{- "data": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
}{- "data": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
}The user to join the session is identified from the jwt_access_token in the request cookies.
| id required | string |
{- "data": {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
}{- "data": [
- {
- "status": "active",
- "id": "abc123",
- "topic": "Graph Algorithms",
- "difficulty": "medium",
- "questionId": "qst567",
- "expiresAt": "2025-11-07T15:00:00Z",
- "createdAt": "2025-11-07T14:00:00Z",
- "updatedAt": "2025-11-07T14:30:00Z"
}
]
}