Weight Loss Nutritionist · GPT-Aktionen
Weight Loss Coach Actions
Backend Actions for the Weight Loss Nutritionist GPT. All numeric computations happen here so the model does not drift on arithmetic. Every response contains a `narrative` string the GPT should echo verbatim.
POST /bmrCompute basal metabolic rate (BMR)Returns Mifflin-St Jeor BMR. CALL THIS instead of doing the math yourself. Pass user_id to persist the profile for future conversations. Echo the returned narrative verbatim.
POST /tdeeCompute total daily energy expenditure (TDEE)Returns TDEE = BMR × activity multiplier. Call this before recommending a calorie goal. Pass user_id to persist the full profile. Echo the returned narrative verbatim.
POST /calorie-goalRecommend a daily calorie goal with safety floors enforcedCore safety-gated endpoint. Enforces calorie floors (1200F/1500M/1600 teen), BMI <19 screen, 1kg/week rate cap, and pregnancy refusal. The `narrative` field is what the GPT should say — do not propose your own numbers on top of this.
POST /macrosCompute protein/fat/carb grams for a daily calorie goalReturns macros based on weight and preference. Protein is pinned to 1.2–1.6 g/kg (balanced), 1.8 g/kg (high_protein), or 1.6 g/kg (keto). Echo the narrative verbatim.
GET /foodLook up calories + macros for a food, scaled to a portionWraps USDA FoodData Central. Returns top matches scaled to the given grams. Applies under-estimation margins for nuts, oils, cheese, fried items, liquid calories, alcohol.
POST /mealEstimate total kcal + macros for a meal from natural-language itemsCall this to tally any meal the user describes. Looks up each item in USDA FDC, applies under-estimation margins, returns per-item + totals with a confidence band. Echo the narrative verbatim.
POST /weight-trendDe-noise a weight history and return the real fat trendApplies a 7-day EMA to filter out water-weight noise, then regresses the last 14 smoothed points for a kg/week slope. Use this before answering "am I plateauing?" or "is this fat or water?". Echo the narrative verbatim.
POST /plateauDiagnose a weight-loss plateau using the playbook checklistRuns the plateau diagnostic from coaching-playbook.md. Returns ranked likely causes and ONE specific adjustment. Call this when the user reports 2+ weeks of no change. Echo the narrative verbatim.
GET /profileRetrieve a saved user profileReturns the biometrics previously saved via calculateBMR or calculateTDEE. Call this at the start of a new conversation to restore the user's context without re-asking all the biometrics.
GET /meal-logGet the user's meal log for a given dateReturns all meals logged today (or a specified date) with running totals. Call this when the user asks 'how much have I eaten today' or at end-of-day for a summary. Echo the narrative verbatim.
Ursprüngliches API-Schema
{
"openapi": "3.1.0",
"info": {
"title": "Weight Loss Coach Actions",
"version": "0.1.0",
"description": "Backend Actions for the Weight Loss Nutritionist GPT. All numeric computations happen here so the model does not drift on arithmetic. Every response contains a `narrative` string the GPT should echo verbatim."
},
"servers": [
{
"url": "https://gpt.nanorhino.ai"
}
],
"components": {
"schemas": {
"BMRResult": {
"type": "object",
"properties": {
"bmr_kcal": {
"type": "number"
},
"method": {
"type": "string",
"enum": [
"mifflin_st_jeor"
]
},
"katch_mcardle_kcal": {
"type": "number"
},
"steps": {
"type": "string"
},
"narrative": {
"type": "string"
},
"profile_saved": {
"type": "boolean"
}
},
"required": [
"bmr_kcal",
"method",
"steps",
"narrative",
"profile_saved"
]
},
"BMRInput": {
"type": "object",
"properties": {
"sex": {
"type": "string",
"enum": [
"male",
"female"
]
},
"age_years": {
"type": "integer",
"minimum": 10,
"maximum": 100
},
"height_cm": {
"type": "number",
"minimum": 120,
"maximum": 230
},
"weight_kg": {
"type": "number",
"minimum": 30,
"maximum": 300
},
"body_fat_pct": {
"type": "number",
"minimum": 3,
"maximum": 60,
"description": "Optional. If provided, Katch-McArdle is returned alongside Mifflin-St Jeor."
},
"user_id": {
"type": "string",
"maxLength": 100,
"description": "Optional user identifier. If provided, biometrics are saved for future reference."
}
},
"required": [
"sex",
"age_years",
"height_cm",
"weight_kg"
]
},
"TDEEResult": {
"type": "object",
"properties": {
"bmr_kcal": {
"type": "number"
},
"tdee_kcal": {
"type": "number"
},
"activity": {
"type": "string",
"enum": [
"sedentary",
"light",
"moderate",
"active",
"very_active"
],
"description": "sedentary (desk job, <10km walking/day), light (1-3x/wk), moderate (3-5x/wk), active (6-7x/wk), very_active (hard daily + physical job)"
},
"multiplier": {
"type": "number"
},
"steps": {
"type": "string"
},
"narrative": {
"type": "string"
},
"profile_saved": {
"type": "boolean"
}
},
"required": [
"bmr_kcal",
"tdee_kcal",
"activity",
"multiplier",
"steps",
"narrative",
"profile_saved"
]
},
"TDEEInput": {
"type": "object",
"properties": {
"sex": {
"type": "string",
"enum": [
"male",
"female"
]
},
"age_years": {
"type": "integer",
"minimum": 10,
"maximum": 100
},
"height_cm": {
"type": "number",
"minimum": 120,
"maximum": 230
},
"weight_kg": {
"type": "number",
"minimum": 30,
"maximum": 300
},
"activity": {
"type": "string",
"enum": [
"sedentary",
"light",
"moderate",
"active",
"very_active"
],
"description": "sedentary (desk job, <10km walking/day), light (1-3x/wk), moderate (3-5x/wk), active (6-7x/wk), very_active (hard daily + physical job)"
},
"user_id": {
"type": "string",
"maxLength": 100,
"description": "Optional user identifier. If provided, the full profile (including activity + TDEE) is saved for future reference."
}
},
"required": [
"sex",
"age_years",
"height_cm",
"weight_kg",
"activity"
]
},
"SafetyIssue": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"below_floor",
"underweight_current",
"underweight_goal",
"unsafe_rate",
"teen",
"pregnant_or_nursing"
]
},
"floor": {
"type": "number"
},
"requested": {
"type": "number"
},
"bmi": {
"type": "number"
},
"goal_bmi": {
"type": "number"
},
"requested_kg_per_week": {
"type": "number"
},
"capped_to": {
"type": "number"
}
},
"required": [
"type"
]
},
"CalorieGoalResult": {
"type": "object",
"properties": {
"tdee_kcal": {
"type": "number"
},
"daily_kcal_goal": {
"type": "number"
},
"deficit_kcal": {
"type": "number"
},
"effective_rate_kg_per_week": {
"type": "number"
},
"weeks_to_goal": {
"type": [
"number",
"null"
]
},
"calorie_floor": {
"type": "number"
},
"safety_issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SafetyIssue"
}
},
"steps": {
"type": "string"
},
"narrative": {
"type": "string"
},
"refusal": {
"type": "boolean",
"description": "True when safety screening refused a deficit. GPT must follow the narrative, not propose its own number."
}
},
"required": [
"tdee_kcal",
"daily_kcal_goal",
"deficit_kcal",
"effective_rate_kg_per_week",
"weeks_to_goal",
"calorie_floor",
"safety_issues",
"steps",
"narrative",
"refusal"
]
},
"CalorieGoalInput": {
"type": "object",
"properties": {
"sex": {
"type": "string",
"enum": [
"male",
"female"
]
},
"age_years": {
"type": "integer",
"minimum": 10,
"maximum": 100
},
"height_cm": {
"type": "number",
"minimum": 120,
"maximum": 230
},
"weight_kg": {
"type": "number",
"minimum": 30,
"maximum": 300
},
"activity": {
"type": "string",
"enum": [
"sedentary",
"light",
"moderate",
"active",
"very_active"
],
"description": "sedentary (desk job, <10km walking/day), light (1-3x/wk), moderate (3-5x/wk), active (6-7x/wk), very_active (hard daily + physical job)"
},
"goal_weight_kg": {
"type": "number",
"minimum": 30,
"maximum": 300
},
"target_rate_kg_per_week": {
"type": "number",
"minimum": 0.1,
"maximum": 2,
"default": 0.5,
"description": "Desired loss rate. Will be capped at 1.0 kg/week."
},
"pregnant_or_nursing": {
"type": "boolean"
}
},
"required": [
"sex",
"age_years",
"height_cm",
"weight_kg",
"activity",
"goal_weight_kg"
]
},
"MacrosResult": {
"type": "object",
"properties": {
"protein_g": {
"type": "number"
},
"fat_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"protein_kcal": {
"type": "number"
},
"fat_kcal": {
"type": "number"
},
"carb_kcal": {
"type": "number"
},
"protein_g_per_kg": {
"type": "number"
},
"steps": {
"type": "string"
},
"narrative": {
"type": "string"
}
},
"required": [
"protein_g",
"fat_g",
"carb_g",
"protein_kcal",
"fat_kcal",
"carb_kcal",
"protein_g_per_kg",
"steps",
"narrative"
]
},
"MacroPreference": {
"type": "string",
"enum": [
"balanced",
"high_protein",
"keto"
],
"default": "balanced"
},
"MacrosInput": {
"type": "object",
"properties": {
"daily_kcal": {
"type": "number",
"minimum": 800,
"maximum": 5000
},
"weight_kg": {
"type": "number",
"minimum": 30,
"maximum": 300
},
"preference": {
"$ref": "#/components/schemas/MacroPreference"
}
},
"required": [
"daily_kcal",
"weight_kg"
]
},
"FoodMatch": {
"type": "object",
"properties": {
"fdc_id": {
"type": "number"
},
"description": {
"type": "string"
},
"brand": {
"type": "string"
},
"grams": {
"type": "number"
},
"kcal": {
"type": "number"
},
"protein_g": {
"type": "number"
},
"fat_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"fiber_g": {
"type": "number"
},
"margin_applied": {
"type": "number"
},
"margin_reasons": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"fdc_id",
"description",
"grams",
"kcal",
"protein_g",
"fat_g",
"carb_g",
"fiber_g"
]
},
"FoodLookupResult": {
"type": "object",
"properties": {
"query": {
"type": "string"
},
"grams": {
"type": "number"
},
"matches": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FoodMatch"
}
},
"confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
]
},
"narrative": {
"type": "string"
}
},
"required": [
"query",
"grams",
"matches",
"confidence",
"narrative"
]
},
"MealItemResult": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"grams": {
"type": "number"
},
"kcal": {
"type": "number"
},
"protein_g": {
"type": "number"
},
"fat_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
]
},
"not_found": {
"type": "boolean",
"description": "True when not in DB — GPT should estimate this item itself."
},
"margin_applied": {
"type": "number"
},
"margin_reasons": {
"type": "array",
"items": {
"type": "string"
}
},
"matched_as": {
"type": "string"
},
"note": {
"type": "string"
}
},
"required": [
"description",
"grams",
"kcal",
"protein_g",
"fat_g",
"carb_g",
"confidence",
"not_found"
]
},
"MealResult": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MealItemResult"
}
},
"total_kcal": {
"type": "number"
},
"total_protein_g": {
"type": "number"
},
"total_fat_g": {
"type": "number"
},
"total_carb_g": {
"type": "number"
},
"confidence_band_kcal": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2,
"description": "[low, high] kcal range"
},
"overall_confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
]
},
"narrative": {
"type": "string"
}
},
"required": [
"items",
"total_kcal",
"total_protein_g",
"total_fat_g",
"total_carb_g",
"confidence_band_kcal",
"overall_confidence",
"narrative"
]
},
"MealItem": {
"type": "object",
"properties": {
"description": {
"type": "string",
"minLength": 1,
"example": "grilled chicken breast"
},
"grams": {
"type": "number",
"minimum": 1,
"maximum": 3000,
"description": "If omitted, a sensible portion is assumed (150g default)."
}
},
"required": [
"description"
]
},
"MealInput": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MealItem"
},
"minItems": 1,
"maxItems": 15
},
"meal_label": {
"type": "string",
"example": "lunch"
}
},
"required": [
"items"
]
},
"WeightTrendResult": {
"type": "object",
"properties": {
"smoothed": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"kg": {
"type": "number"
}
},
"required": [
"date",
"kg"
]
}
},
"latest_smoothed_kg": {
"type": "number"
},
"slope_kg_per_week": {
"type": "number"
},
"label": {
"type": "string",
"enum": [
"true_trend_down",
"true_trend_up",
"flat_noise",
"insufficient_data"
]
},
"raw_range_kg": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2,
"description": "[min, max] of raw readings"
},
"narrative": {
"type": "string"
}
},
"required": [
"smoothed",
"latest_smoothed_kg",
"slope_kg_per_week",
"label",
"raw_range_kg",
"narrative"
]
},
"WeightReading": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "ISO date",
"example": "2026-04-10"
},
"kg": {
"type": "number",
"minimum": 30,
"maximum": 300
}
},
"required": [
"date",
"kg"
]
},
"WeightTrendInput": {
"type": "object",
"properties": {
"readings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeightReading"
},
"minItems": 3,
"maxItems": 180
}
},
"required": [
"readings"
]
},
"PlateauCause": {
"type": "object",
"properties": {
"cause": {
"type": "string",
"enum": [
"outdated_tdee",
"tracking_drift",
"new_exercise_water",
"high_sodium",
"luteal_phase",
"actual_plateau"
]
},
"likelihood": {
"type": "string",
"enum": [
"high",
"medium",
"low"
]
},
"adjustment": {
"type": "string"
}
},
"required": [
"cause",
"likelihood",
"adjustment"
]
},
"PlateauResult": {
"type": "object",
"properties": {
"weeks_stalled": {
"type": "number"
},
"ranked_causes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PlateauCause"
}
},
"recommended_adjustment": {
"type": "string"
},
"narrative": {
"type": "string"
}
},
"required": [
"weeks_stalled",
"ranked_causes",
"recommended_adjustment",
"narrative"
]
},
"PlateauInput": {
"type": "object",
"properties": {
"weeks_stalled": {
"type": "number",
"minimum": 1,
"maximum": 52
},
"kg_lost_since_tdee_recalc": {
"type": "number",
"minimum": 0,
"maximum": 100,
"default": 0
},
"started_new_exercise_last_4_weeks": {
"type": "boolean",
"default": false
},
"high_sodium_recently": {
"type": "boolean",
"default": false
},
"in_luteal_phase": {
"type": "boolean"
},
"tracking_confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
],
"default": "medium"
},
"avg_daily_kcal_logged": {
"type": "number"
},
"current_tdee_estimate_kcal": {
"type": "number"
}
},
"required": [
"weeks_stalled"
]
},
"ProfileResult": {
"type": "object",
"properties": {
"found": {
"type": "boolean"
},
"profile": {
"type": [
"object",
"null"
],
"properties": {
"user_id": {
"type": "string"
},
"sex": {
"type": "string",
"enum": [
"male",
"female"
]
},
"age_years": {
"type": "number"
},
"height_cm": {
"type": "number"
},
"weight_kg": {
"type": "number"
},
"activity": {
"type": [
"string",
"null"
]
},
"body_fat_pct": {
"type": [
"number",
"null"
]
},
"bmr_kcal": {
"type": [
"number",
"null"
]
},
"tdee_kcal": {
"type": [
"number",
"null"
]
},
"updated_at": {
"type": "string"
}
},
"required": [
"user_id",
"sex",
"age_years",
"height_cm",
"weight_kg",
"activity",
"body_fat_pct",
"bmr_kcal",
"tdee_kcal",
"updated_at"
]
},
"narrative": {
"type": "string"
}
},
"required": [
"found",
"profile",
"narrative"
]
},
"MealLogEntry": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"meal_label": {
"type": [
"string",
"null"
]
},
"total_kcal": {
"type": "number"
},
"total_protein_g": {
"type": "number"
},
"total_fat_g": {
"type": "number"
},
"total_carb_g": {
"type": "number"
},
"confidence": {
"type": "string"
},
"logged_at": {
"type": "string"
}
},
"required": [
"id",
"meal_label",
"total_kcal",
"total_protein_g",
"total_fat_g",
"total_carb_g",
"confidence",
"logged_at"
]
},
"MealLogResult": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"meals": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MealLogEntry"
}
},
"day_total_kcal": {
"type": "number"
},
"day_total_protein_g": {
"type": "number"
},
"day_total_fat_g": {
"type": "number"
},
"day_total_carb_g": {
"type": "number"
},
"meal_count": {
"type": "number"
},
"narrative": {
"type": "string"
}
},
"required": [
"date",
"meals",
"day_total_kcal",
"day_total_protein_g",
"day_total_fat_g",
"day_total_carb_g",
"meal_count",
"narrative"
]
}
},
"parameters": {}
},
"paths": {
"/bmr": {
"post": {
"operationId": "calculateBMR",
"summary": "Compute basal metabolic rate (BMR)",
"description": "Returns Mifflin-St Jeor BMR. CALL THIS instead of doing the math yourself. Pass user_id to persist the profile for future conversations. Echo the returned narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BMRInput"
}
}
}
},
"responses": {
"200": {
"description": "BMR with arithmetic shown",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BMRResult"
}
}
}
}
}
}
},
"/tdee": {
"post": {
"operationId": "calculateTDEE",
"summary": "Compute total daily energy expenditure (TDEE)",
"description": "Returns TDEE = BMR × activity multiplier. Call this before recommending a calorie goal. Pass user_id to persist the full profile. Echo the returned narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TDEEInput"
}
}
}
},
"responses": {
"200": {
"description": "TDEE with steps",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TDEEResult"
}
}
}
}
}
}
},
"/calorie-goal": {
"post": {
"operationId": "recommendCalorieGoal",
"summary": "Recommend a daily calorie goal with safety floors enforced",
"description": "Core safety-gated endpoint. Enforces calorie floors (1200F/1500M/1600 teen), BMI <19 screen, 1kg/week rate cap, and pregnancy refusal. The `narrative` field is what the GPT should say — do not propose your own numbers on top of this.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CalorieGoalInput"
}
}
}
},
"responses": {
"200": {
"description": "Calorie goal, or a refusal narrative if safety issues were triggered",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CalorieGoalResult"
}
}
}
}
}
}
},
"/macros": {
"post": {
"operationId": "calculateMacros",
"summary": "Compute protein/fat/carb grams for a daily calorie goal",
"description": "Returns macros based on weight and preference. Protein is pinned to 1.2–1.6 g/kg (balanced), 1.8 g/kg (high_protein), or 1.6 g/kg (keto). Echo the narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MacrosInput"
}
}
}
},
"responses": {
"200": {
"description": "Macro grams with steps",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MacrosResult"
}
}
}
}
}
}
},
"/food": {
"get": {
"operationId": "lookupFood",
"summary": "Look up calories + macros for a food, scaled to a portion",
"description": "Wraps USDA FoodData Central. Returns top matches scaled to the given grams. Applies under-estimation margins for nuts, oils, cheese, fried items, liquid calories, alcohol.",
"parameters": [
{
"schema": {
"type": "string",
"minLength": 1,
"example": "grilled chicken breast"
},
"required": true,
"name": "query",
"in": "query"
},
{
"schema": {
"type": "number",
"minimum": 1,
"maximum": 5000,
"default": 100
},
"required": false,
"name": "grams",
"in": "query"
}
],
"responses": {
"200": {
"description": "Top matches",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FoodLookupResult"
}
}
}
},
"502": {
"description": "Upstream FDC error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"narrative": {
"type": "string"
}
},
"required": [
"error",
"narrative"
]
}
}
}
}
}
}
},
"/meal": {
"post": {
"operationId": "estimateMealCalories",
"summary": "Estimate total kcal + macros for a meal from natural-language items",
"description": "Call this to tally any meal the user describes. Looks up each item in USDA FDC, applies under-estimation margins, returns per-item + totals with a confidence band. Echo the narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MealInput"
}
}
}
},
"responses": {
"200": {
"description": "Meal totals",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MealResult"
}
}
}
}
}
}
},
"/weight-trend": {
"post": {
"operationId": "smoothWeightTrend",
"summary": "De-noise a weight history and return the real fat trend",
"description": "Applies a 7-day EMA to filter out water-weight noise, then regresses the last 14 smoothed points for a kg/week slope. Use this before answering \"am I plateauing?\" or \"is this fat or water?\". Echo the narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WeightTrendInput"
}
}
}
},
"responses": {
"200": {
"description": "Smoothed trend",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WeightTrendResult"
}
}
}
}
}
}
},
"/plateau": {
"post": {
"operationId": "diagnosePlateau",
"summary": "Diagnose a weight-loss plateau using the playbook checklist",
"description": "Runs the plateau diagnostic from coaching-playbook.md. Returns ranked likely causes and ONE specific adjustment. Call this when the user reports 2+ weeks of no change. Echo the narrative verbatim.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PlateauInput"
}
}
}
},
"responses": {
"200": {
"description": "Ranked causes + one adjustment",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PlateauResult"
}
}
}
}
}
}
},
"/profile": {
"get": {
"operationId": "getProfile",
"summary": "Retrieve a saved user profile",
"description": "Returns the biometrics previously saved via calculateBMR or calculateTDEE. Call this at the start of a new conversation to restore the user's context without re-asking all the biometrics.",
"parameters": [
{
"schema": {
"type": "string",
"maxLength": 100,
"default": "default",
"description": "User identifier. Defaults to \"default\" for single-user mode."
},
"required": false,
"name": "user_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "Profile if found, or found=false",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProfileResult"
}
}
}
}
}
}
},
"/meal-log": {
"get": {
"operationId": "getMealLog",
"summary": "Get the user's meal log for a given date",
"description": "Returns all meals logged today (or a specified date) with running totals. Call this when the user asks 'how much have I eaten today' or at end-of-day for a summary. Echo the narrative verbatim.",
"parameters": [
{
"schema": {
"type": "string",
"description": "ISO date (YYYY-MM-DD). Defaults to today (UTC).",
"example": "2026-04-14"
},
"required": false,
"name": "date",
"in": "query"
}
],
"responses": {
"200": {
"description": "Day's meals with running totals",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MealLogResult"
}
}
}
}
}
}
}
},
"webhooks": {}
}