Skip to main content

AI Nutrition API

AI Nutrition provides AI-powered meal analysis, food logging, nutrition planning, and a wellness chatbot for authenticated users.

Authentication

Use a Firebase user token in the Authorization: Bearer <firebase_jwt> header.

note

The AI Nutrition module must be enabled for your client. Contact your administrator if you receive a module-disabled error.

Nutrition Plans

GET /api/ai-nutrition/plans

Returns the user's nutrition plans.

Response
{
"plans": [
{
"planId": "plan-001",
"goal": "LOSE",
"dailyCalories": 2000,
"macros": {
"protein": 150,
"carbs": 200,
"fats": 65
},
"targetWeight": "70",
"bmi": "22.5",
"explanation": "Based on your profile, a moderate calorie deficit...",
"foodSuggestions": [
{ "name": "Grilled chicken breast", "reason": "High protein, low fat" },
{ "name": "Brown rice", "reason": "Complex carbs for sustained energy" }
],
"isActive": true,
"createdAt": "2026-03-17T10:00:00Z"
}
]
}

POST /api/ai-nutrition/generate-plan

Generate a personalized nutrition plan using AI. Deactivates any previously active plan.

Request Body:

FieldTypeRequiredDescription
goal"LOSE" | "MAINTAIN" | "GAIN"YesNutrition goal
targetWeightstringNoTarget weight
exerciseFrequencystringNoHow often the user exercises
dietaryStaplestringNoPrimary dietary staple
bodyFramestringNoBody frame description
healthFocusstringNoHealth focus area
Request
{
"goal": "LOSE",
"targetWeight": "70",
"exerciseFrequency": "3-4 times per week",
"dietaryStaple": "rice",
"healthFocus": "heart health"
}
Response
{
"planId": "plan-002",
"dailyCalories": 1800,
"macros": {
"protein": 135,
"carbs": 180,
"fats": 60
},
"bmi": "24.1",
"explanation": "Your personalized plan focuses on...",
"foodSuggestions": [
{ "name": "Salmon", "reason": "Rich in omega-3 for heart health" },
{ "name": "Oats", "reason": "High fiber to support weight loss" }
]
}

Meal Analysis

POST /api/ai-nutrition/analyze-meal

Analyze a food image using AI to extract nutritional information.

Responses follow the requested language so the returned meal description and food name match the client UI locale.

Request Body:

FieldTypeRequiredDescription
imageBase64stringYesBase64-encoded food image
language"en" | "zh-Hant" | "zh-Hans"NoResponse language (default: "en")
Request
{
"imageBase64": "<base64-encoded-image>",
"language": "en"
}
Response
{
"analysisId": "analysis-001",
"text": "This appears to be a grilled chicken salad with mixed greens, providing a good balance of protein and fiber.",
"foodData": {
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"sugar": 4,
"healthScore": 82
},
"createdAt": "2026-03-17T12:30:00Z"
}

Food Logs

POST /api/ai-nutrition/food-logs

Log a food entry.

Request Body:

FieldTypeRequiredDescription
namestringYesFood name
caloriesnumberYesCalories (min: 0)
proteinnumberYesProtein in grams (min: 0)
carbsnumberYesCarbohydrates in grams (min: 0)
fatsnumberYesFats in grams (min: 0)
sugarnumberNoSugar in grams (min: 0)
healthScorenumberNoHealth score (0–100)
imageUrlstringNoImage URL
source"scan" | "manual" | "chat"NoLog source (default: "manual")
analysisIdstringNoLink to a meal analysis
Request
{
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"source": "scan",
"analysisId": "analysis-001"
}
Response (201)
{
"logId": "log-001",
"clientId": "gofa",
"userId": "user-001",
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"source": "scan",
"analysisId": "analysis-001",
"date": "2026-03-17",
"createdAt": "2026-03-17T12:35:00Z"
}

GET /api/ai-nutrition/food-logs

Get food logs for a specific date, or fetch recent history for the authenticated user.

Query Parameters:

ParameterTypeDefaultDescription
datestringTodayDate in YYYY-MM-DD format
limitnumberNo defaultWhen provided without date, returns the most recent logs up to the specified limit (max 100)
Response
{
"date": "2026-03-17",
"logs": [
{
"logId": "log-001",
"clientId": "gofa",
"userId": "user-001",
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"sugar": 4,
"healthScore": 82,
"source": "scan",
"date": "2026-03-17",
"createdAt": "2026-03-17T12:35:00Z"
}
]
}
Response (Recent History)
{
"date": null,
"limit": 20,
"logs": [
{
"logId": "log-001",
"clientId": "gofa",
"userId": "user-001",
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"sugar": 4,
"healthScore": 82,
"source": "scan",
"analysisId": "analysis-001",
"date": "2026-03-17",
"createdAt": "2026-03-17T12:35:00Z"
}
]
}

GET /api/ai-nutrition/food-logs/[logId]

Get a single food log entry for the authenticated user. If the log was created from a meal scan, the linked AI analysis is also returned when available.

Response
{
"log": {
"logId": "log-001",
"clientId": "gofa",
"userId": "user-001",
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"sugar": 4,
"healthScore": 82,
"source": "scan",
"analysisId": "analysis-001",
"imageUrl": null,
"date": "2026-03-17",
"createdAt": "2026-03-17T12:35:00Z"
},
"analysis": {
"analysisId": "analysis-001",
"clientId": "gofa",
"userId": "user-001",
"imageUrl": null,
"foodData": {
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"sugar": 4,
"healthScore": 82
},
"aiInsights": "A balanced, protein-forward meal with moderate fats and relatively low carbohydrates.",
"logged": true,
"createdAt": "2026-03-17T12:30:00Z"
}
}

DELETE /api/ai-nutrition/food-logs/[logId]

Delete a food log entry. Users can only delete their own logs.

Response
{
"success": true
}

Error Responses:

StatusDescription
403User does not own this log
404Food log not found

Chat

POST /api/ai-nutrition/chat

Send a message to the AI wellness chatbot. Supports text messages and optional image attachments. The chatbot can suggest food items to log based on the conversation.

Responses follow the requested language so the returned answer matches the client UI locale.

Request Body:

FieldTypeRequiredDescription
messagestringYesUser message (min: 1 character)
imageBase64string | nullNoOptional image attachment
conversationIdstringNoExisting conversation ID to continue a thread
language"en" | "zh-Hant" | "zh-Hans"NoResponse language (default: "en")
Request
{
"message": "I just had a banana and a glass of milk for breakfast",
"conversationId": "conv-001",
"language": "en"
}
Response
{
"conversationId": "conv-001",
"response": "A banana with milk is a great quick breakfast! The banana provides about 105 calories with potassium and fiber, while the milk adds protein and calcium.",
"suggestedFoodLog": {
"name": "Banana and Milk",
"calories": 250,
"protein": 10,
"carbs": 40,
"fats": 5,
"sugar": 28
}
}
note

When the chatbot returns a suggestedFoodLog, clients can present it to the user and submit it via the POST /api/ai-nutrition/food-logs endpoint if the user confirms.

Admin Records

GET /api/ai-nutrition/records

Admin-only endpoint to list food log records for a client. Requires admin authentication.

Query Parameters:

ParameterTypeDefaultDescription
clientIdstringTarget client ID (admin can query other clients)
limitnumber50Max results (1–500)
Response
{
"data": [
{
"id": "log-001",
"clientId": "gofa",
"userId": "user-001",
"name": "Grilled Chicken Salad",
"calories": 350,
"protein": 30,
"carbs": 15,
"fats": 18,
"date": "2026-03-17",
"createdAt": "2026-03-17T12:35:00.000Z",
"timestamp": "2026-03-17T12:35:00.000Z"
}
],
"count": 1
}

Error Responses:

StatusDescription
401Unauthorized — admin authentication required
403AI Nutrition module not enabled for this client
500Internal server error
note

Results are ordered by createdAt descending. The AI Nutrition module must be enabled for the target client.