-
Notifications
You must be signed in to change notification settings - Fork 0
API Documentation
Dinesh Dawonauth edited this page Jul 22, 2025
·
1 revision
Complete reference for My Progress Planner REST API endpoints.
Development: http://localhost:3000/api
Production: https://your-domain.com/api
Most endpoints require user authentication via Supabase JWT tokens.
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/jsonAll API responses follow this consistent structure:
interface APIResponse<T> {
data: T | null;
error: string | null;
meta?: {
total?: number;
page?: number;
limit?: number;
};
}GET /api/meals/todayResponse:
{
"data": {
"breakfast": {
"id": "uuid",
"content": "Oatmeal with berries",
"ai_response": "What a nutritious start to your day! π",
"logged_at": "2025-01-15T08:30:00Z"
},
"lunch": null,
"dinner": null
},
"error": null
}POST /api/meals/logRequest Body:
{
"mealType": "breakfast" | "lunch" | "dinner",
"content": "Scrambled eggs with toast"
}Response:
{
"data": {
"meal": {
"id": "uuid",
"content": "Scrambled eggs with toast",
"ai_response": "Perfect protein to fuel your morning! π",
"logged_at": "2025-01-15T08:30:00Z"
}
},
"error": null
}GET /api/meals/check?type=breakfastResponse:
{
"data": {
"exists": true,
"content": "Oatmeal with berries",
"logged_at": "2025-01-15T08:30:00Z"
},
"error": null
}GET /api/streakResponse:
{
"data": {
"current_streak": 7,
"best_streak": 14,
"streak_start_date": "2025-01-08",
"total_days": 45
},
"error": null
}GET /api/summaries?page=1&limit=10Response:
{
"data": [
{
"id": "uuid",
"summary_date": "2025-01-15",
"content": "You had an amazing day with all three meals logged! π",
"meals_count": 3,
"created_at": "2025-01-15T23:00:00Z"
}
],
"meta": {
"total": 25,
"page": 1,
"limit": 10
},
"error": null
}GET /api/summaries/2025-01-15Response:
{
"data": {
"summary_date": "2025-01-15",
"content": "You had an amazing day with all three meals logged! π",
"meals_count": 3,
"meals": [
{
"meal_type": "breakfast",
"content": "Oatmeal with berries",
"logged_at": "2025-01-15T08:30:00Z"
}
]
},
"error": null
}POST /api/ai/chatRequest Body:
{
"mealType": "breakfast",
"content": "Greek yogurt with granola",
"context": {
"streak": 5,
"previousMeals": [],
"timeOfDay": "morning"
}
}Response:
{
"data": {
"response": "Greek yogurt with granola sounds absolutely delicious! π",
"metadata": {
"tokens_used": 45,
"model": "gpt-4",
"response_time_ms": 1250
}
},
"error": null
}GET /api/ai/quoteResponse:
{
"data": {
"quote": "Every meal is an opportunity to nourish yourself with love! π",
"cached": true
},
"error": null
}GET /api/user/profileResponse:
{
"data": {
"id": "uuid",
"name": "John Doe",
"email": "[email protected]",
"friend_code": "LOVE123",
"created_at": "2025-01-01T00:00:00Z"
},
"error": null
}PUT /api/user/nameRequest Body:
{
"name": "John Smith"
}GET /api/user/friend-codeResponse:
{
"data": {
"friend_code": "LOVE123"
},
"error": null
}GET /api/friends/search?code=LOVE456Response:
{
"data": {
"user": {
"name": "Jane Doe",
"friend_code": "LOVE456"
}
},
"error": null
}GET /api/friendsResponse:
{
"data": [
{
"friend_code": "LOVE456",
"name": "Jane Doe",
"added_at": "2025-01-10T00:00:00Z"
}
],
"error": null
}POST /api/notifications/subscribeRequest Body:
{
"subscription": {
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"keys": {
"p256dh": "key_data",
"auth": "auth_data"
}
}
}POST /api/notifications/testNote: Requires admin authentication via
ADMIN_PASSWORD
GET /api/admin/statsHeaders:
Authorization: Bearer <admin_password>Response:
{
"data": {
"total_users": 1250,
"total_meals": 15680,
"active_users_today": 245,
"meals_today": 892,
"avg_streak": 5.2
},
"error": null
}GET /api/admin/summariesPOST /api/admin/log-mealRequest Body:
{
"userId": "user_uuid",
"mealType": "breakfast",
"content": "Test meal for debugging"
}GET /api/cron/lunch- Schedule: Daily at 6:00 PM UTC (18:00)
- Purpose: Send lunch logging reminders
GET /api/cron/dinner- Schedule: Daily at 1:00 AM UTC (01:00)
- Purpose: Send dinner logging reminders
Authentication:
Authorization: Bearer <CRON_SECRET>| Code | Message | Description |
|---|---|---|
400 |
Bad Request | Invalid request data |
401 |
Unauthorized | Missing or invalid authentication |
403 |
Forbidden | Insufficient permissions |
404 |
Not Found | Resource doesn't exist |
409 |
Conflict | Meal already logged for this type/date |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server-side error |
{
"data": null,
"error": "Meal already logged for breakfast today"
}- General API: 100 requests/hour per user
- AI Endpoints: 20 requests/hour per user
- Admin Endpoints: 200 requests/hour per IP
# Get today's meals
curl -H "Authorization: Bearer YOUR_JWT" \
https://your-domain.com/api/meals/today
# Log a meal
curl -X POST \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{"mealType":"breakfast","content":"Pancakes"}' \
https://your-domain.com/api/meals/log// Utility function for API calls
async function apiCall<T>(endpoint: string, options?: RequestInit): Promise<T> {
const response = await fetch(`/api${endpoint}`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});
return response.json();
}
// Example usage
const meals = await apiCall('/meals/today');
const result = await apiCall('/meals/log', {
method: 'POST',
body: JSON.stringify({
mealType: 'breakfast',
content: 'Oatmeal with berries'
})
});Planned webhook endpoints for external integrations:
-
POST /api/webhooks/meal-logged- Triggered when meal is logged -
POST /api/webhooks/streak-milestone- Triggered on streak milestones -
POST /api/webhooks/summary-generated- Triggered when daily summary is created
-
Cache First:
/api/ai/quote,/api/user/name -
Network First:
/api/meals/log,/api/ai/chat -
Stale While Revalidate:
/api/meals/check,/api/streak
Failed API calls are queued and retried when connection is restored:
- Meal logging
- AI response generation
- User profile updates
- API Issues: Open an issue
- Questions: GitHub Discussions
-
Email:
[email protected]