Log a meal
log_mealAdds- What it does
- Adds a new record and leaves what you had alone. Safe to retry: the same call twice changes nothing more.
- Permission
- Meals, change
meals:write
What your assistant is told
Log a meal for the user. Each item is EITHER a catalog reference
{food_id, quantity_g} OR an inline estimate {name, energy_kcal,
protein_g, carb_g, fat_g, fiber_g?} — and a single meal can mix both.
PHOTO FLOW: if the user shared a PHOTO of their food with you, call
list_my_ingredients ONCE first — for each component that is clearly
one of theirs, pass {food_id, quantity_g} and say which one you picked;
estimate the rest inline. Do not run search_foods for every
component. The photo is NEVER sent to this server (only you see it).
For inline items, energy_kcal and the gram macros are ABSOLUTE totals
for the portion (not per 100 g). Break a plate into one item per
component. State your portion/prep assumptions back to the user.
Pass at_iso (when eaten) and a stable idempotency_key so retries
don't duplicate the meal. at_iso MUST carry the user's UTC offset — an
offsetless timestamp is refused, because the server would have to guess
the zone and a late-night meal would land in the wrong day; if you don't
know their offset, ask for it rather than sending a bare wall-clock. If
the user logged this by tapping a saved shortcut, pass quick_add_id so
its usage stays accurate. Returns the saved meal with computed totals.
THE RETURN CARRIES TWO HINTS about saving this as a quick add — a saved
shortcut the user can then log in one tap from the app:
- similar_logs_near_this_hour — how many past meals in the last 8 weeks
shared an item with this one at around this time of day.
- existing_quick_add — whether a shortcut already covers roughly this.
When that count is HIGH and existing_quick_add is false, you MAY offer
to save one with create_quick_add. The discipline is strict:
- AT MOST ONE offer per conversation, and only when the user isn't
mid-task. Never chain offers.
- NEVER off a single logged meal — one data point is not a routine, and a
low count means no offer at all.
- NEVER re-offer something the user declined, in this conversation or a
later one; a "no" is permanent.
- Frame it ONLY as a shortcut — "want me to save this so you can log it in
one tap?" — never as a finding, a recommendation, or an observation
about what they eat. Do not tell the user how often they eat something,
do not praise consistency, and do not mention streaks or adherence.
This app deliberately has none of that.
A low count, a missing count, or a true existing_quick_add all mean the
same thing: say nothing and move on.
Parameters
itemslist of object, requiredItems eaten. EITHER {food_id, quantity_g} OR {name + absolute macros}.at_isotext, requiredWhen the meal was eaten, ISO-8601 WITH the user's UTC offset (e.g. 2026-06-17T12:30:00Z or 2026-06-17T23:30:00+03:00). Required; if you don't know their offset, ask.idempotency_keytext, requiredIdempotency key; reuse on retry to avoid duplicate meals.meal_typetext, optionalOptional meal type: breakfast | lunch | dinner | snack.quick_add_idid, optionalOptional id of the saved quick add this meal came from (fromlist_quick_adds); bumps its usage. An unknown id is ignored.