Relay is a collaborative developer workspace built with MERN stack (MongoDB, Express, React 19, Node.js). The API provides comprehensive endpoints for authentication, note management, code snippets, tasks, real-time collaboration, and AI-powered search.
Production: https://relay-workspace-llm.vercel.app/api
Development: http://localhost:3000/api
All authenticated endpoints require a Bearer token in the Authorization header:
Authorization: Bearer {token}
Tokens are obtained from the login or register endpoints and expire after 30 days.
POST /users/register
Content-Type: application/json
{
"username": "johndoe",
"email": "john@example.com",
"password": "SecurePass123!"
}
Response (201):
{
"id": "507f1f77bcf86cd799439011",
"username": "johndoe",
"email": "john@example.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
POST /users/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "SecurePass123!"
}
Response (200):
{
"id": "507f1f77bcf86cd799439011",
"username": "johndoe",
"email": "john@example.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
GET /users/me
Authorization: Bearer {token}
Response (200):
{
"_id": "507f1f77bcf86cd799439011",
"username": "johndoe",
"email": "john@example.com",
"createdAt": "2026-07-01T12:00:00Z",
"updatedAt": "2026-07-01T12:00:00Z"
}
POST /users/forgot-password
Content-Type: application/json
{
"email": "john@example.com"
}
Response (200):
{
"message": "Reset link sent"
}
POST /users/reset-password/{token}
Content-Type: application/json
{
"password": "NewSecurePass123!"
}
Response (200):
{
"message": "Password updated successfully"
}
GET /notes
Authorization: Bearer {token}
Response (200):
[
{
"_id": "507f1f77bcf86cd799439012",
"title": "My Note",
"content": "Rich text content...",
"userId": "507f1f77bcf86cd799439011",
"createdAt": "2026-07-01T12:00:00Z",
"updatedAt": "2026-07-01T12:00:00Z"
}
]
POST /notes
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "New Note",
"content": "Note content here..."
}
Response (201):
{
"_id": "507f1f77bcf86cd799439012",
"title": "New Note",
"content": "Note content here...",
"userId": "507f1f77bcf86cd799439011",
"createdAt": "2026-07-01T12:00:00Z"
}
PUT /notes/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "Updated Note",
"content": "Updated content..."
}
Response (200):
{
"_id": "507f1f77bcf86cd799439012",
"title": "Updated Note",
"content": "Updated content...",
"updatedAt": "2026-07-01T12:15:00Z"
}
DELETE /notes/{id}
Authorization: Bearer {token}
Response (200):
{
"message": "Note deleted"
}
GET /snippets
Authorization: Bearer {token}
Response (200):
[
{
"_id": "507f1f77bcf86cd799439013",
"title": "QuickSort",
"code": "function quickSort(arr) { ... }",
"language": "javascript",
"tags": ["algorithms", "sorting"],
"userId": "507f1f77bcf86cd799439011",
"createdAt": "2026-07-01T12:00:00Z"
}
]
POST /snippets
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "BinarySearch",
"code": "function binarySearch(arr, target) { ... }",
"language": "javascript",
"tags": ["algorithms", "searching"]
}
Response (201):
{
"_id": "507f1f77bcf86cd799439013",
"title": "BinarySearch",
"code": "function binarySearch(arr, target) { ... }",
"language": "javascript",
"tags": ["algorithms", "searching"],
"userId": "507f1f77bcf86cd799439011",
"createdAt": "2026-07-01T12:00:00Z"
}
GET /search?query=binary%20search
Authorization: Bearer {token}
Response (200):
{
"results": [
{
"type": "snippet",
"title": "Binary Search Implementation",
"relevance": 0.95,
"content": "..."
}
],
"totalResults": 1
}
GET /search?query=algorithm&type=snippet&language=javascript
Authorization: Bearer {token}
Response (200):
{
"results": [...],
"filters": {
"type": "snippet",
"language": "javascript"
}
}
GET /tasks
Authorization: Bearer {token}
Response (200):
[
{
"_id": "507f1f77bcf86cd799439014",
"title": "Complete API Documentation",
"description": "Add comprehensive API docs",
"status": "in-progress",
"priority": "high",
"dueDate": "2026-07-10",
"userId": "507f1f77bcf86cd799439011"
}
]
POST /tasks
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "Implement feature X",
"description": "Add new feature to workspace",
"priority": "medium",
"dueDate": "2026-07-15"
}
Response (201):
{
"_id": "507f1f77bcf86cd799439014",
"title": "Implement feature X",
"description": "Add new feature to workspace",
"status": "pending",
"priority": "medium",
"dueDate": "2026-07-15",
"userId": "507f1f77bcf86cd799439011"
}
PATCH /tasks/{id}/status
Authorization: Bearer {token}
Content-Type: application/json
{
"status": "completed"
}
Response (200):
{
"_id": "507f1f77bcf86cd799439014",
"status": "completed",
"updatedAt": "2026-07-01T12:30:00Z"
}
POST /ai/generate
Authorization: Bearer {token}
Content-Type: application/json
{
"prompt": "Write a function to sort an array",
"model": "gemini",
"temperature": 0.7
}
Response (200):
{
"completion": "function sortArray(arr) { ... }",
"tokens": {
"input": 15,
"output": 120
}
}
POST /ai/explain
Authorization: Bearer {token}
Content-Type: application/json
{
"code": "const arr = [3,1,2]; arr.sort((a,b) => a-b);"
}
Response (200):
{
"explanation": "This code sorts an array of numbers...",
"language": "javascript"
}
POST /compiler/execute
Authorization: Bearer {token}
Content-Type: application/json
{
"code": "print('Hello, World!')",
"language": "python",
"input": ""
}
Response (200):
{
"output": "Hello, World!",
"executionTime": "0.05s",
"memory": "2.1MB",
"status": "success"
}
POST /compiler/check-syntax
Authorization: Bearer {token}
Content-Type: application/json
{
"code": "const x = 5",
"language": "javascript"
}
Response (200):
{
"valid": true,
"errors": []
}
POST /upload
Authorization: Bearer {token}
Content-Type: multipart/form-data
Form Data:
- file: (binary file, max 5MB)
Response (200):
{
"url": "https://res.cloudinary.com/..."
}
- AI Routes: 10 requests per 60 seconds
- Compiler Routes: 15 requests per 60 seconds
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1656744660
{
"message": "Rate limit exceeded. Please try again later.",
"retryAfter": 45
}| Status | Meaning | Example |
|---|---|---|
| 200 | OK | Successful GET/PUT/PATCH |
| 201 | Created | Successful POST |
| 400 | Bad Request | Missing fields, invalid data |
| 401 | Unauthorized | Missing or invalid token |
| 403 | Forbidden | User doesn't own resource |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal server error |
{
"message": "Error description",
"error": {
"details": "Additional error information"
}
}// Client emits
socket.emit('editNote', { noteId, content, userId });
// Server broadcasts
socket.on('noteUpdated', (data) => {
// Update note in real-time
});// User joins workspace
socket.emit('userJoined', { workspaceId, userId });
// Receive active users list
socket.on('activeUsers', (users) => {});{
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"pages": 8
}
}{
"results": [
{
"id": "123",
"title": "Binary Search",
"relevance": 0.98,
"type": "snippet"
}
],
"queryTime": "0.04ms"
}-
Token Management
- Store tokens securely (httpOnly cookie recommended)
- Refresh tokens before expiration
- Clear tokens on logout
-
Input Validation
- All endpoints validate input fields
- XSS prevention with DOMPurify
- Rate limiting on sensitive operations
-
CORS Configuration
- Restricted to whitelisted domains
- Credentials included in requests
- Preflight requests handled
-
Password Security
- Bcrypt hashing with salt (10 rounds)
- Password strength validation
- Secure password reset tokens
- Average Response Time: < 200ms
- Database Query Optimization: Indexed fields
- Caching Layer: Redis for frequently accessed data
- Vector Search: MongoDB Atlas Vector Search for semantic queries
// Connect to workspace
const socket = io('https://relay-workspace-llm.vercel.app', {
auth: {
token: 'your_jwt_token'
}
});
// Events
socket.on('connect', () => console.log('Connected'));
socket.on('noteSync', (data) => {});
socket.on('taskUpdate', (data) => {});
socket.on('disconnect', () => console.log('Disconnected'));- GitHub: manaskng/relay
- Issues: Report Bug
- Email: manasraj_23cs238@dtu.ac.in
API Documentation v1.0 | Last Updated: July 1, 2026