Portal
SandboxAPI v1Not signed inExternal user: —

Meal planning

Own the calendar UX in your app — let FoodAPI store the plan, rank recipes, and compute what is missing from the pantry.

What you can build

Weekly planners, “plan tonight” flows, pantry-aware suggestions, and shopping lists that start from scheduled meals.

What FoodAPI owns vs your app

  • FoodAPI stores meal plans and entries, ranks recipes (RECOMMENDATION), scores feasibility, and aggregates shopping gaps.
  • Your app owns calendar layout, drag-and-drop, notifications, and which suggestions the user accepts.

1. Create a meal plan

Plans are revisioned documents. Create with a date range and timezone; add recipe entries immediately or afterward.

plan = client.meal_plans.create(
    payload={
        "name": "Week of Sept 14",
        "start_date": "2026-09-14",
        "end_date": "2026-09-20",
        "timezone": "America/Denver",
        "status": "draft",
    },
    external_user_id="user_42",
)
print(plan.id, plan.revision)

2. Rank recipes, then attach meals

Use reasoning to pick candidates, then write accepted recipes onto the plan. Entry writes require the current revision (optimistic concurrency).

page = client.recipes.list(search="tacos", limit=10)
seed = page.items[0]

recs = client.reason(
    recipe_id=seed.id,
    goal="RECOMMENDATION",
    dietary_preferences=["VEGETARIAN"],
    pantry_item_ids=[i.id for i in client.pantry.list(external_user_id="user_42").items],
    external_user_id="user_42",
)
chosen_id = (
    recs.alternative_recipes[0].recipe_id
    if recs.alternative_recipes
    else seed.id
)

mutation = client.meal_plans.entries.create(
    plan.id,
    expected_revision=plan.revision,
    payload={
        "scheduled_date": "2026-09-15",
        "meal_slot": "dinner",
        "entry_type": "recipe",
        "recipe_id": str(chosen_id),
        "intended_servings": "4",
    },
    external_user_id="user_42",
)
plan_revision = mutation.revision
print(mutation.entry.id, plan_revision)

3. Check pantry feasibility for a meal

pantry = client.pantry.list(external_user_id="user_42")
feasibility = client.reason(
    recipe_id=chosen_id,
    goal="FEASIBILITY",
    pantry_item_ids=[i.id for i in pantry.items],
    external_user_id="user_42",
)
print(feasibility.feasibility_score, feasibility.missing_ingredients)

4. Derive shopping from planned recipes

Collect recipe ids from plan entries, then call shopping intelligence (next guide).

entries = client.meal_plans.entries.list(plan.id, external_user_id="user_42")
recipe_ids = [e.recipe_id for e in entries.items if e.recipe_id]

missing = client.shopping.missing_ingredients(
    recipe_ids=recipe_ids,
    external_user_id="user_42",
)
for row in missing.missing_ingredients:
    print(row.canonical_name, row.missing_quantity, row.missing_unit)

Production considerations

  • Partition with external_user_id / externalUserId so each end user has isolated plans and pantry.
  • Always send expected_revision on entry create/update/delete to avoid lost writes.
  • MCP agents can call plan_meals (requires meal-plan read/write scopes). MCP tools · Scopes

Next

Close the loop