Nutrition FunctionsCook Pro
These functions are available in any report template when you're signed in with Cook Pro. They resolve your ingredients against a curated nutrition database (USDA and other reference sources) with unit and preparation conversion. Prefer to maintain your own numbers? The free local db() datastore works without a subscription.
| Function | Returns |
|---|---|
nutrition_for(ingredient) | macros — kcal, protein_g, fat_g, carb_g, fiber_g |
nutrition_for_amount(name, amount, unit, prep) | full item: macros + micronutrients + vitamins |
aggregate_nutrition(ingredients) | items, totals, confidence breakdown, allergen summary |
total_calories(ingredients) | number |
macros(ingredients) | {kcal, protein_g, …} |
vitamins(ingredients) | vitamin totals |
nutrient_total(ingredients, key) | one nutrient, e.g. "iron_mg", "vit_d_iu" |
is_in_category(ingredient, slug) | true/false, category-tree aware |
category_servings(plan, slug) | meals containing the category (see plans) |
convert(amount, from, to, ingredient?) | unit conversion; pass the ingredient for volume/count units |
compare(actual, target, op) / within_tol(actual, target, tol_pct) | assertions (see checks) |
record_check, all_checks(), failed_checks() | pass/fail tracking (see checks) |
Reading nutrition
nutrition_for(ingredient) uses the quantity, unit and preparation from the recipe itself:
{% set n = nutrition_for(ingredient) %}
{{ n.kcal }} kcal, {{ n.protein_g }} g protein
For micronutrients and vitamins, or when there's no ingredient object to hand, use the lower-level form:
{{ nutrition_for_amount("salmon", 150, "g", "cooked").protein_g }}
aggregate_nutrition(ingredients) sums a whole list in one call and is the workhorse for recipe and plan totals; total_calories, macros, vitamins and nutrient_total are shortcuts over it.
Allergens
Every resolved item carries an allergens block, and aggregate_nutrition adds an allergen_summary for the batch. The one rule that matters: check status before contains. An ingredient with status: "unverified" has an empty contains list that means "nothing known" — never "allergen-free".
You don't have to hand-write the logic — include the built-in "allergens" partial and it renders the standard, correctly guarded lines:
{% set alg = aggregate_nutrition(ingredients).allergen_summary %}
{% include "allergens" %}
When some ingredients are unverified, the summary reads "Contains at least …" — the list is a floor, not a ceiling.
Confidence & sources
Nutrition numbers are estimates, and the report can be honest about it. aggregate_nutrition returns a confidence_breakdown next to the totals:
{% set t = aggregate_nutrition(ingredients) %}
Overall: {{ t.totals.confidence }} (weighted: {{ t.totals.confidence_weighted }})
totals.confidence— worst-of across items (strict).totals.confidence_weighted— mass-weighted, so one small estimated item doesn't tank the score.confidence_breakdown.estimated_share_of_micronutrients— how much of the micronutrient totals comes from estimated entries.
Each item also carries its own source and confidence, so templates can flag individual rows.
Categories & conversion
is_in_category(ingredient, slug) is tree-aware — an oily fish counts as fish_and_shellfish too. convert(amount, from, to, ingredient?) converts units; pass the ingredient when converting volume or count units that need density or portion data.
Building reports outside the editor, with the API or CLI? See the developer guides.