Skip to main content

API Reference

Overview

Bike4Mind's API follows a RESTful design pattern using Next.js API routes. The API is built with Express-like middleware, comprehensive error handling, and JWT-based authentication. All endpoints follow consistent patterns for authentication, authorization, and response formatting.

Base Configuration

API Structure

/api/
├── ai/ # AI services and processing
├── users/ # User management
├── organizations/ # Organization CRUD operations
├── api-keys/ # API key management
├── subscriptions/ # Billing and subscription management
├── analytics/ # Event tracking and analytics
├── [type]/[id]/ # Generic resource endpoints
└── utility endpoints # Health checks, ping, etc.

Middleware Stack

baseApi()

The core middleware that provides:

  • Authentication: JWT token validation
  • Authorization: User permission checking
  • CORS: Cross-origin request handling
  • Error Handling: Standardized error responses
  • Request Parsing: JSON and form data parsing
// Usage Example
const handler = baseApi().get(async (req, res) => {
// req.user is automatically populated if authenticated
// req.ability contains user permissions
return res.json({ data: 'response' });
});

asyncHandler()

Wraps async functions to handle errors automatically:

const handler = baseApi().get(
asyncHandler(async (req, res) => {
// Automatic error catching and response
const data = await someAsyncOperation();
return res.json(data);
})
);

Authentication

JWT Token Authentication

  • Header: Authorization: Bearer <token>
  • User Context: Available as req.user in handlers
  • Permissions: Available as req.ability (CASL-based)

Optional Authentication

// Disable authentication for public endpoints
const handler = baseApi({ auth: false }).get(async (req, res) => {
// Public endpoint logic
});

AI Services API

Audio Transcription

POST /api/ai/transcribe

Transcribe audio files using OpenAI Whisper.

Request:

  • Content-Type: multipart/form-data
  • Body: Audio file upload

Response:

{
"text": "Transcribed audio content"
}

Example:

const formData = new FormData();
formData.append('file', audioFile);

const response = await fetch('/api/ai/transcribe', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});

Image Generation

POST /api/ai/generate-image

Generate images using AWS Bedrock.

Request:

{
"prompt": "A serene mountain landscape",
"style": "photorealistic",
"size": "1024x1024"
}

Response:

{
"questId": "quest_123",
"status": "queued",
"estimatedTime": 30
}

LLM Inference

POST /api/infer

Direct LLM inference for text generation.

Request:

{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "Explain quantum computing"
}
],
"stream": false
}

Response:

{
"result": "Quantum computing is a revolutionary approach..."
}

User Management API

Get User Profile

GET /api/users/[id]

Retrieve user profile information.

Parameters:

  • id: User ID

Response:

{
"_id": "user_123",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"organizationId": "org_456",
"isAdmin": false,
"preferences": {
"theme": "dark",
"language": "en"
}
}

List Users

GET /api/users

List users with filtering and pagination.

Query Parameters:

  • page: Page number (default: 1)
  • limit: Items per page (default: 10)
  • search: Search term
  • organizationId: Filter by organization
  • role: Filter by role

Response:

{
"users": [
{
"_id": "user_123",
"username": "john_doe",
"email": "john@example.com"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 25,
"pages": 3
}
}

Organization Management API

List Organizations

GET /api/organizations

List organizations accessible to the user.

Query Parameters:

  • page: Page number
  • limit: Items per page
  • search: Search term

Response:

{
"organizations": [
{
"_id": "org_123",
"name": "Acme Corp",
"slug": "acme-corp",
"subscriptionTier": "pro",
"memberCount": 15
}
]
}

Create Organization

POST /api/organizations

Create a new organization.

Request:

{
"name": "New Organization",
"description": "Organization description"
}

Response:

{
"_id": "org_456",
"name": "New Organization",
"slug": "new-organization",
"subscriptionStatus": "trial"
}

API Key Management

List API Keys

GET /api/api-keys

List user's API keys (obfuscated).

Response:

{
"apiKeys": [
{
"_id": "key_123",
"name": "OpenAI Production",
"service": "openai",
"keyPreview": "sk-...xyz",
"isActive": true,
"lastUsedAt": "2024-01-15T10:30:00Z"
}
]
}

Delete API Key

DELETE /api/api-keys/[id]/delete

Delete an API key.

Parameters:

  • id: API key ID

Response:

{
"success": true,
"message": "API key deleted successfully"
}

Set Active API Key

POST /api/api-keys/[id]/set-active

Set an API key as active for a service.

Parameters:

  • id: API key ID

Response:

{
"success": true,
"message": "API key set as active"
}

Subscription Management

Get User Subscriptions

GET /api/subscriptions/own

Get current user's subscriptions.

Response:

{
"subscriptions": [
{
"_id": "sub_123",
"status": "active",
"tier": "pro",
"currentPeriodEnd": "2024-02-15T00:00:00Z",
"creditsRemaining": 1500
}
]
}

List All Subscriptions (Admin)

GET /api/subscriptions

List all subscriptions (admin only).

Query Parameters:

  • search: Search term
  • page: Page number
  • limit: Items per page

Response:

{
"subscriptions": [
{
"_id": "sub_123",
"userId": "user_456",
"organizationId": "org_789",
"status": "active",
"tier": "enterprise"
}
],
"pagination": {
"total": 50,
"page": 1,
"pages": 5
}
}

Analytics & Tracking

Log Event

POST /api/analytics/log-event

Track user events and analytics.

Request:

{
"event": "quest_completed",
"properties": {
"questId": "quest_123",
"duration": 45000,
"tokensUsed": 1250
}
}

Response:

204 No Content

Generic Resource Endpoints

Get Resource

GET /api/[type]/[id]

Generic endpoint for retrieving resources.

Parameters:

  • type: Resource type (e.g., 'invite', 'project')
  • id: Resource ID

Example:

GET /api/invite/inv_123

Resource Invites

GET /api/[type]/[id]/invites

Get invites for a resource.

POST /api/[type]/[id]/invites

Create an invite for a resource.

Revoke Sharing

POST /api/[type]/[id]/revokeSharing

Revoke sharing permissions for a resource.

Utility Endpoints

Health Check

GET /api/ping

Simple health check endpoint.

Response:

{
"message": "pong"
}

Settings

GET /api/settings/fetch

Fetch user settings and preferences.

Response:

{
"theme": "dark",
"language": "en",
"notifications": {
"email": true,
"slack": false
}
}

Error Handling

Standard Error Response

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input parameters",
"details": {
"field": "email",
"issue": "Invalid email format"
}
}
}

HTTP Status Codes

CodeDescription
200Success
201Created
204No Content
400Bad Request
401Unauthorized
403Forbidden
404Not Found
422Validation Error
500Internal Server Error

Error Types

Authentication Errors

{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired token"
}
}

Authorization Errors

{
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions"
}
}

Validation Errors

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": [
{
"field": "email",
"message": "Email is required"
}
]
}
}

Rate Limiting

Default Limits

  • Authenticated requests: 1000 requests/hour
  • AI endpoints: 100 requests/hour
  • File uploads: 50 requests/hour

Rate Limit Headers

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200

Pagination

Standard Pagination

{
"data": [...],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"pages": 10,
"hasNext": true,
"hasPrev": false
}
}

Query Parameters

  • page: Page number (1-based)
  • limit: Items per page (max 100)
  • sort: Sort field
  • order: Sort order ('asc' or 'desc')

WebSocket API

Connection

const ws = new WebSocket('wss://api.bike4mind.com/websocket');

Message Format

{
"action": "subscribe_query",
"data": {
"query": "sessions",
"filters": {
"userId": "user_123"
}
}
}

Supported Actions

  • subscribe_query: Subscribe to data changes
  • unsubscribe_query: Unsubscribe from data changes
  • heartbeat: Keep connection alive

SDK Examples

JavaScript/TypeScript

class Bike4MindAPI {
constructor(private token: string, private baseUrl: string) {}

async get(endpoint: string) {
const response = await fetch(`${this.baseUrl}${endpoint}`, {
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
}
});
return response.json();
}

async post(endpoint: string, data: any) {
const response = await fetch(`${this.baseUrl}${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
return response.json();
}
}

// Usage
const api = new Bike4MindAPI(token, 'https://api.bike4mind.com');
const users = await api.get('/api/users');

Python

import requests

class Bike4MindAPI:
def __init__(self, token, base_url):
self.token = token
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}

def get(self, endpoint):
response = requests.get(f'{self.base_url}{endpoint}', headers=self.headers)
return response.json()

def post(self, endpoint, data):
response = requests.post(f'{self.base_url}{endpoint}',
json=data, headers=self.headers)
return response.json()

# Usage
api = Bike4MindAPI(token, 'https://api.bike4mind.com')
users = api.get('/api/users')

This API reference provides comprehensive documentation for integrating with Bike4Mind's backend services, supporting both direct HTTP requests and WebSocket connections for real-time functionality.