Meal drafts and confidence

The draft an assistant sends to log_meal, ingredient confidence tiers (0.85, 0.60, 0.30) and when a meal needs review.

In ChatGPT and Claude the host model does the vision: it looks at the photo or reads what the person said and sends log_meal a draft. Gutlog matches each item against the person's own foods, the barcode index and the food database, then portions it, computes nutrients and stores it. Gutlog's own analysis of photos from the web app, the CLI and the API produces the same draft, so there is one contract for both paths. The field descriptions below are what the model reads in the tool schema.

Example

log_meal input
{  "title": "Scrambled eggs on toast",  "meal_type": "breakfast",  "client": "claude",  "items": [    {      "name": "scrambled eggs",      "grams": 120,      "confidence": 0.92,      "portion_confidence": 0.7,      "cooking_method": "pan_fried",      "ingredients": [        {          "name": "egg",          "confidence": 0.97,          "visible": true        },        {          "name": "butter",          "confidence": 0.55,          "visible": false        },        {          "name": "milk",          "confidence": 0.35,          "visible": false        }      ]    },    {      "name": "sourdough toast",      "portion": {        "quantity": 1,        "unit": "slice"      },      "confidence": 0.85,      "ingredients": [        {          "name": "wheat flour",          "confidence": 0.9,          "visible": false        },        {          "name": "salt",          "confidence": 0.75,          "visible": false        }      ]    }  ]}

The meal

* marks a required field. meal_type is one of breakfast | lunch | dinner | snack | drink.

FieldTypeWhat to send
items *arrayOne entry per distinct food or drink on the plate or in the message.
meal_typeenumLeave out to infer from the time.
eaten_atstringWhen it was eaten, ISO 8601 with offset; default now.
titlestringA short name for the meal: "Chipotle bowl", "Breakfast".
notestringAnything the person said that is not an item (where, how they felt).
clientstringYour client name, e.g. "chatgpt", "claude", "cursor".
modelstringYour model name, for calibration.

Items

One item per distinct food or drink. Send grams when you can estimate the weight from the photo (plate size, utensils, a hand), otherwise a household portion. A readable barcode makes the product's label win over estimates. cooking_method is one of 15 values such as grilled, pan_fried or unknown.

FieldTypeWhat to send
name *stringThe item as it would appear on a menu or label: "grilled chicken breast", "white rice", "oat milk latte".
food_idstringA food id from search_foods or a previous log_meal reply, when you already know the match.
barcodestringBarcode digits if you can read them (UPC/EAN); the product's label then wins over estimates.
brandstringBrand when packaging shows it.
gramsnumberYour estimate of the edible weight in grams. Prefer this when you can estimate it from the photo (plate size, utensils, hand).
portionobjectInstead of grams: "2 slices", "1 cup", "1 medium".
servingsnumberNumber of the product's servings (with a barcode).
confidencenumberHow sure you are of what this item is, 0–1.
portion_confidencenumberHow sure you are of the amount, 0–1.
cooking_methodenum
ingredientsarrayIngredients with a confidence each, most certain first. Include hidden fats, sugars, onion and garlic when plausible.
label_textstringAny ingredient list or nutrition label text you can read, verbatim.

Ingredients

Most certain first. Include hidden fats, sugars, onion and garlic when they are plausible, at 0.30 to 0.60: they matter for calories and for gut tracking, and the person is asked rather than assumed.

FieldTypeWhat to send
name *stringOne ingredient as a person would say it: "garlic", "olive oil", "cheddar".
confidence *numberHow sure you are it is in this item, 0–1. ≥0.85 you can see or were told it; 0.60–0.85 very likely for this dish; 0.30–0.60 plausible but hidden (cooking fat, butter, sugar, garlic, onion in a sauce): include these, they are asked about. Omit below 0.30.
visiblebooleanYou can see it in the photo (true) or inferred it from the dish (false).
ingredient_idstringCanonical ingredient id if you know it from a previous response; otherwise leave it out.

Confidence tiers

TierConfidenceWhat happens
confirmed≥ 0.85, or read from a labelIncluded and counted in the meal.
likely0.6 to 0.85Included, counted and pre-selected: one tap or "yes" confirms them all.
possible0.3 to 0.6Suggested, not counted. Asked about, highest confidence first.
droppedunder 0.3Not stored. Leave these out of the draft.

An ingredient's status starts as included (confirmed, likely) or suggested (possible), and becomes confirmed or rejected when the person answers.

Always logged; sometimes reviewed

  • The meal is always stored: nothing waits for a confirmation.
  • needs_review is set when the meal's confidence is under the person's threshold (default 0.8), when a possible ingredient is one of their known triggers or allergens, or when a portion looks implausible.
  • The answer carries at most 3 questions about possible ingredients. Reply with one line of what was logged, then ask them.
  • Corrections always win over estimates, and every one is kept with who made it and from where.
log_meal result (shortened)
{  "meal_id": "6f1c2e0a-4b7d-4c2e-9a51-0d3b8e7f9a10",  "needs_review": false,  "totals_display": {    "kcal": 352,    "protein_g": 19.8,    "carbs_g": 24.1,    "fat_g": 19.6  },  "items": [    {      "name": "scrambled eggs",      "grams": 120,      "ingredients": [        {          "name": "egg",          "tier": "confirmed",          "confidence": 0.97,          "status": "included"        },        {          "name": "butter",          "tier": "possible",          "confidence": 0.55,          "status": "suggested"        },        {          "name": "milk",          "tier": "possible",          "confidence": 0.35,          "status": "suggested"        }      ]    },    {      "name": "sourdough toast",      "grams": 50,      "ingredients": [        {          "name": "wheat flour",          "tier": "confirmed",          "confidence": 0.9,          "status": "included"        },        {          "name": "salt",          "tier": "likely",          "confidence": 0.75,          "status": "included"        }      ]    }  ],  "questions": [    "Butter in the eggs?",    "A splash of milk in the eggs?"  ]}

Amounts in results are integers in each nutrient's base unit; see nutrients and units. Logging a draft is free and unlimited on every plan.