Skip to content

Latest commit

 

History

History
618 lines (497 loc) · 10.4 KB

File metadata and controls

618 lines (497 loc) · 10.4 KB

📚 RELAY API DOCUMENTATION

Overview

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.


🔐 Authentication

Base URL

Production: https://relay-workspace-llm.vercel.app/api
Development: http://localhost:3000/api

Authentication Method: JWT Bearer Token

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.


📡 API Endpoints

1. Authentication Routes

Register User

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

Login User

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 Current User

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

Forgot Password

POST /users/forgot-password
Content-Type: application/json

{
  "email": "john@example.com"
}

Response (200):
{
  "message": "Reset link sent"
}

Reset Password

POST /users/reset-password/{token}
Content-Type: application/json

{
  "password": "NewSecurePass123!"
}

Response (200):
{
  "message": "Password updated successfully"
}

2. Notes Routes

Get All Notes

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

Create Note

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

Update Note

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 Note

DELETE /notes/{id}
Authorization: Bearer {token}

Response (200):
{
  "message": "Note deleted"
}

3. Code Snippets Routes

Get All Snippets

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

Create Snippet

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

4. Search Routes (RAG-Based)

Semantic Search

GET /search?query=binary%20search
Authorization: Bearer {token}

Response (200):
{
  "results": [
    {
      "type": "snippet",
      "title": "Binary Search Implementation",
      "relevance": 0.95,
      "content": "..."
    }
  ],
  "totalResults": 1
}

Advanced Search Filters

GET /search?query=algorithm&type=snippet&language=javascript
Authorization: Bearer {token}

Response (200):
{
  "results": [...],
  "filters": {
    "type": "snippet",
    "language": "javascript"
  }
}

5. Tasks Routes

Get All Tasks

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

Create Task

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

Update Task Status

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

6. AI Routes (Rate Limited: 10 req/min)

Generate Completion

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

Code Explanation

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

7. Compiler Routes (Rate Limited: 15 req/min)

Execute Code

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

Syntax Check

POST /compiler/check-syntax
Authorization: Bearer {token}
Content-Type: application/json

{
  "code": "const x = 5",
  "language": "javascript"
}

Response (200):
{
  "valid": true,
  "errors": []
}

8. Upload Routes

Upload Image/File

POST /upload
Authorization: Bearer {token}
Content-Type: multipart/form-data

Form Data:
- file: (binary file, max 5MB)

Response (200):
{
  "url": "https://res.cloudinary.com/..."
}

⏱️ Rate Limiting

Applied Endpoints:

  • AI Routes: 10 requests per 60 seconds
  • Compiler Routes: 15 requests per 60 seconds

Rate Limit Headers:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1656744660

Rate Limit Response (429):

{
  "message": "Rate limit exceeded. Please try again later.",
  "retryAfter": 45
}

🔍 Error Handling

Common Status Codes:

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

Error Response Format:

{
  "message": "Error description",
  "error": {
    "details": "Additional error information"
  }
}

🚀 Real-Time Features (WebSocket)

Socket.io Events:

Note Collaboration

// Client emits
socket.emit('editNote', { noteId, content, userId });

// Server broadcasts
socket.on('noteUpdated', (data) => {
  // Update note in real-time
});

Live Presence

// User joins workspace
socket.emit('userJoined', { workspaceId, userId });

// Receive active users list
socket.on('activeUsers', (users) => {});

📊 Response Examples

Paginated Response

{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "pages": 8
  }
}

Search Results with Relevance

{
  "results": [
    {
      "id": "123",
      "title": "Binary Search",
      "relevance": 0.98,
      "type": "snippet"
    }
  ],
  "queryTime": "0.04ms"
}

🔒 Security Best Practices

  1. Token Management

    • Store tokens securely (httpOnly cookie recommended)
    • Refresh tokens before expiration
    • Clear tokens on logout
  2. Input Validation

    • All endpoints validate input fields
    • XSS prevention with DOMPurify
    • Rate limiting on sensitive operations
  3. CORS Configuration

    • Restricted to whitelisted domains
    • Credentials included in requests
    • Preflight requests handled
  4. Password Security

    • Bcrypt hashing with salt (10 rounds)
    • Password strength validation
    • Secure password reset tokens

📈 Performance Metrics

  • 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

🔄 WebSocket Connection

// 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'));

📞 Support


API Documentation v1.0 | Last Updated: July 1, 2026