Complete reference for all REST API endpoints in the FitBox meal delivery platform.
Last Updated: 2025-11-01
API Version: v1
Base URL: /api
Purpose: Register a new user account
Request Body:
{
email: string; // Valid email address
password: string; // Min 8 characters
name: string; // Full name
phone?: string; // Optional phone number
}Response: 201 Created
{
user: {
id: string
email: string
name: string
}
}Validation:
- Email must be unique
- Password: min 8 chars, 1 uppercase, 1 lowercase, 1 number
- Name: required, non-empty
File: src/app/api/auth/signup/route.ts
Purpose: Get CSRF token for state-changing operations
Response: 200 OK
{
csrfToken: string
}File: src/app/api/auth/csrf/route.ts
Purpose: NextAuth.js authentication handler
Authentication Methods:
- Credentials (email/password)
- Session management
- Token refresh
File: src/app/api/auth/[...nextauth]/route.ts
Purpose: Get available meal bundle options
Query Parameters:
type(optional):subscription|one-time
Response: 200 OK
{
bundles: [
{
id: string;
size: number; // 6, 8, 10, 12 meals
basePrice: number; // Regular price
subscriptionPrice: number; // 5% discount
description: string;
}
]
}Business Logic:
- 6 meals: $85 base / $80.75 subscription
- 8 meals: $110 base / $104.50 subscription
- 10 meals: $135 base / $128.25 subscription
- 12 meals: $160 base / $152.00 subscription
File: src/app/api/bundles/route.ts
Purpose: Retrieve user's shopping cart
Authentication: Required
Response: 200 OK
{
cart: {
items: [
{
mealId: string;
name: string;
price: number;
quantity: number;
image: string;
}
];
subtotal: number;
total: number;
}
}File: src/app/api/cart/route.ts
Purpose: Add meal to cart
Authentication: Required
Request Body:
{
mealId: string
quantity: number // Default: 1
}Response: 201 Created
{
cart: {
items: CartItem[];
subtotal: number;
total: number;
}
}File: src/app/api/cart/route.ts
Purpose: Remove meal from cart
Authentication: Required
Path Parameters:
mealId: Meal identifier
Response: 200 OK
File: src/app/api/cart/[mealId]/route.ts
Purpose: Get current week's meal menu
Response: 200 OK
{
menu: {
id: string;
weekStartDate: string; // ISO 8601
weekEndDate: string;
meals: [
{
id: string;
name: string;
nameEn: string;
nameFr: string;
descriptionEn: string;
descriptionFr: string;
price: number;
image: string;
allergens: string[];
dietaryInfo: string[];
nutritionInfo: {
calories: number;
protein: number;
carbs: number;
fat: number;
};
}
];
}
}Business Logic:
- Menu releases Tuesday 12 PM (Sunday delivery) and Saturday 12 PM (Wednesday delivery)
- 6 meal options per week
File: src/app/api/weekly-menu/route.ts
Purpose: Get current active menu
Response: 200 OK (same format as /api/weekly-menu)
File: src/app/api/menus/current/route.ts
Purpose: Get detailed meal information
Path Parameters:
id: Meal identifier
Response: 200 OK
{
meal: {
id: string;
name: string;
nameEn: string;
nameFr: string;
descriptionEn: string;
descriptionFr: string;
price: number;
image: string;
allergens: string[];
dietaryInfo: string[];
nutritionInfo: object;
ingredients: string[];
preparationTime: number;
}
}File: src/app/api/meals/[id]/route.ts
Purpose: Get user's active subscriptions
Authentication: Required
Response: 200 OK
{
subscriptions: [
{
id: string;
bundleSize: number;
status: "ACTIVE" | "PAUSED" | "CANCELLED";
billingCycle: "WEEKLY";
nextBillingDate: string; // ISO 8601
nextDeliveryDate: string;
price: number;
selectedMeals: string[]; // Meal IDs
}
]
}File: src/app/api/subscriptions/route.ts
Purpose: Create new subscription
Authentication: Required
Request Body:
{
bundleId: string
deliveryAddressId: string
startDate: string // ISO 8601
}Response: 201 Created
File: src/app/api/subscriptions/route.ts
Purpose: Get subscription details
Authentication: Required (owner only)
Path Parameters:
id: Subscription identifier
Response: 200 OK
File: src/app/api/subscriptions/[id]/route.ts
Purpose: Update subscription
Authentication: Required (owner only)
Request Body (partial update):
{
deliveryAddressId?: string;
status?: "ACTIVE" | "PAUSED" | "CANCELLED";
}Response: 200 OK
File: src/app/api/subscriptions/[id]/route.ts
Purpose: Pause subscription temporarily
Authentication: Required (owner only)
Request Body:
{
resumeDate: string // ISO 8601
}Response: 200 OK
File: src/app/api/subscriptions/[id]/pause/route.ts
Purpose: Get selected meals for subscription
Authentication: Required (owner only)
Response: 200 OK
{
meals: Meal[];
selectionDeadline: string; // ISO 8601
autoSelected: boolean;
}File: src/app/api/subscriptions/[id]/meals/route.ts
Purpose: Select meals for upcoming week
Authentication: Required (owner only)
Request Body:
{
mealIds: string[]; // Must match bundle size
}Response: 200 OK
Business Logic:
- Selection deadline: Tuesday 6 PM (Sunday delivery) or Saturday 6 PM (Wednesday delivery)
- If deadline missed: System auto-selects 3 recommended meals
- Meal count must match subscription bundle size
File: src/app/api/subscriptions/[id]/meals/route.ts
Purpose: Get user profile information
Authentication: Required
Response: 200 OK
{
user: {
id: string;
email: string;
name: string;
phone?: string;
createdAt: string;
loyaltyPoints: number;
}
}File: src/app/api/users/profile/route.ts
Purpose: Update user profile
Authentication: Required
Request Body (partial update):
{
name?: string;
phone?: string;
}Response: 200 OK
File: src/app/api/users/profile/route.ts
Purpose: Get user's delivery addresses
Authentication: Required
Response: 200 OK
{
addresses: [
{
id: string;
street: string;
city: string;
province: string;
postalCode: string;
isDefault: boolean;
deliveryInstructions?: string;
}
]
}File: src/app/api/users/addresses/route.ts
Purpose: Add new delivery address
Authentication: Required
Request Body:
{
street: string;
city: string;
province: string; // Must be "BC"
postalCode: string; // Must be valid Vancouver area
isDefault?: boolean;
deliveryInstructions?: string;
}Response: 201 Created
Validation:
- Postal code must be valid Greater Vancouver Area
- Province must be BC
- Address validated against delivery zones
File: src/app/api/users/addresses/route.ts
Purpose: Update delivery address
Authentication: Required (owner only)
Path Parameters:
id: Address identifier
Request Body (partial update):
{
street?: string;
city?: string;
postalCode?: string;
isDefault?: boolean;
deliveryInstructions?: string;
}Response: 200 OK
File: src/app/api/users/addresses/[id]/route.ts
Purpose: Delete delivery address
Authentication: Required (owner only)
Response: 200 OK
File: src/app/api/users/addresses/[id]/route.ts
Purpose: Get all delivery zones
Response: 200 OK
{
zones: [
{
id: string;
name: string;
postalCodePrefixes: string[];
deliveryDays: string[]; // ["SUNDAY", "WEDNESDAY"]
deliveryFee: number;
}
]
}File: src/app/api/delivery-zones/route.ts
Purpose: Validate postal code for delivery coverage
Request Body:
{
postalCode: string // Format: "V6B 1A1"
}Response: 200 OK
{
valid: boolean;
zone?: {
id: string;
name: string;
deliveryDays: string[];
deliveryFee: number;
};
error?: string;
}Validation:
- Format: Canadian postal code (A1A 1A1)
- Province: British Columbia (V prefix)
- Coverage: Greater Vancouver Area only
File: src/app/api/delivery-zones/validate/route.ts
Purpose: Get delivery date availability
Query Parameters:
postalCode: Postal code to checkstartDate: Start date (ISO 8601)
Response: 200 OK
{
availableDates: [
{
date: string; // ISO 8601
dayOfWeek: string; // "SUNDAY" | "WEDNESDAY"
timeWindow: string; // "5:30 PM - 10:00 PM"
available: boolean;
}
]
}File: src/app/api/delivery-zones/availability/route.ts
Purpose: Automated meal selection for missed deadlines (cron job)
Authentication: Required (system/admin only)
Process:
- Find subscriptions with no meal selection after deadline
- Select 3 recommended meals based on:
- Previous selections
- Popular meals
- Dietary preferences
- Send notification to user
Schedule: Runs at 6:15 PM on Tuesdays and Saturdays
File: src/app/api/cron/auto-selection/route.ts
All endpoints follow a consistent error response format:
{
error: {
code: "VALIDATION_ERROR",
message: "Invalid request data",
details: {
field: "Specific validation error"
}
},
status: 400
}{
error: {
code: "UNAUTHORIZED",
message: "Authentication required"
},
status: 401
}{
error: {
code: "FORBIDDEN",
message: "Insufficient permissions"
},
status: 403
}{
error: {
code: "NOT_FOUND",
message: "Resource not found"
},
status: 404
}{
error: {
code: "INTERNAL_ERROR",
message: "An unexpected error occurred"
},
status: 500
}Rate limits by endpoint category:
- Authentication: 5 requests/minute
- Payment/Checkout: 10 requests/minute
- General API: 100 requests/minute
- Background Jobs: No limit (internal only)
- GET /api/bundles
- GET /api/weekly-menu
- GET /api/menus/current
- GET /api/meals/[id]
- GET /api/delivery-zones
- POST /api/delivery-zones/validate
- GET /api/delivery-zones/availability
- POST /api/auth/signup
- GET /api/auth/csrf
- All /api/cart/* endpoints
- All /api/subscriptions/* endpoints
- All /api/users/* endpoints
- POST /api/cron/auto-selection
- API Contracts - OpenAPI specification
- Technical Architecture - System architecture
- Business Requirements - Feature specifications
- Testing Guide - API testing methodology
Note: All endpoints implement proper security measures including input validation, SQL injection prevention, XSS protection, and CSRF protection for state-changing operations.