All API reference pages

Culinary resources

The food graph: ingredients → recipes → menu items → menus → a dated, site-specific effective menu that the rest of the platform reads. Writes require manageCulinary (manager+) unless noted.

Ingredients

GET  /orgs/{orgId}/ingredients
POST /orgs/{orgId}/ingredients
PUT  /orgs/{orgId}/ingredients/{id}

An ingredient carries its base unit, cost per unit, density, allergens, diet flags, and nutrition per 100 g/ml.

Recipes and versions

GET   /orgs/{orgId}/recipes                    — list (with computed roll-ups)
POST  /orgs/{orgId}/recipes                    — create the recipe shell
GET   /orgs/{orgId}/recipes/{id}               — detail incl. versions
PUT   /orgs/{orgId}/recipes/{id}               — update name/category/station/tags
POST  /orgs/{orgId}/recipes/{id}/versions      — add a version (draft or published)
POST  /orgs/{orgId}/recipes/{id}/archive
PATCH /orgs/{orgId}/recipes/{id}/image         — attach a plate photo (media id)
POST  /orgs/{orgId}/import/culinary            — CSV import (ingredients/recipes)

Recipes are versioned: the version document holds yield, portions, components (ingredients or sub-recipes), method steps with CCPs, and texture/diet variants. Publishing a version computes and freezes cost per portion, nutrition per portion, and the allergen/diet roll-up — returned on the recipe as computed:

{
  "id": "23f67f69-3531-4d17-b9b2-a1aac236ce4d",
  "name": "Ahi Poke-Style Bowl",
  "category": "bowl",
  "station": "cold",
  "status": "active",
  "currentVersionId": "83537e82-e837-40c1-87db-2d32199e6a11",
  "portions": 24,
  "computed": {
    "warnings": [],
    "allergens": ["fish", "soy"],
    "dietFlags": ["gluten_free"],
    "costPerPortion": 4.6,
    "nutritionEstimated": false,
    "nutritionPerPortion": { "kcal": 477.1, "proteinG": 44.94, "sodiumMg": 139.2 }
  },
  "imageUrl": "https://miseline.keyedsystems.com/api/media/content/..."
}

(nutritionPerPortion is abbreviated here — the real object carries the full nutrient set.) nutritionEstimated: true flags AI-estimated inputs pending dietitian review.

GET   /orgs/{orgId}/menu-items
POST  /orgs/{orgId}/menu-items
PUT   /orgs/{orgId}/menu-items/{id}
PATCH /orgs/{orgId}/menu-items/{id}/image

A menu item wraps a recipe (or stands alone) with category, serving text, price in cents, and an image. Allergen and diet flags flow up from the recipe.

GET  /orgs/{orgId}/menus
POST /orgs/{orgId}/menus                        — kinds: daily | cycle | static | catering
GET  /orgs/{orgId}/menus/{id}
PUT  /orgs/{orgId}/menus/{id}
PUT  /orgs/{orgId}/menus/{id}/slots             — replace the slot grid
POST /orgs/{orgId}/menus/{id}/plan/move         — move a slot on the planner
POST /orgs/{orgId}/menus/{id}/plan/copy-day
POST /orgs/{orgId}/menus/{id}/submit-review     — freeze a snapshot, status → pending_review
POST /orgs/{orgId}/menus/{id}/publish

Slots place a menu item at day (or date) × day part × station, with alternates and texture variants. Menus under RD review follow draft → pending_review → approved → published; signoffs record the decisions:

GET  /orgs/{orgId}/signoffs
POST /orgs/{orgId}/signoffs                     — request a review
POST /orgs/{orgId}/signoffs/{id}/decide         — approve/reject (requires the rd credential)

Assignments and the effective menu

GET  /orgs/{orgId}/menu-assignments
POST /orgs/{orgId}/menu-assignments             — place a cycle menu on a site calendar
PUT  /orgs/{orgId}/menu-assignments/{id}
GET  /orgs/{orgId}/effective-menu?siteId=…&date=YYYY-MM-DD

The effective menu resolves the assignment (anchor date + rotation weeks) for a site and date and returns the menu, the resolved cycle day, and slots grouped by day part — this is what production generation, tray lines, boards, and order lists consume:

{
  "assignment": { "menuId": "ce60318d-...", "startDate": "2026-06-28", "anchorDate": "2026-07-06", "active": true },
  "menu": { "id": "ce60318d-...", "name": "Tower Café Week", "kind": "cycle", "cycleWeeks": 1 },
  "dayIndex": 5,
  "dayParts": [ { "dayPart": "breakfast", "slots": [ ... ] } ]
}

Nutrition targets

GET/POST /orgs/{orgId}/population-targets       — DRI-based or custom nutrient bands
PUT      /orgs/{orgId}/population-targets/{id}
PUT      /orgs/{orgId}/menus/{id}/population-target      — attach to a menu
PUT      /orgs/{orgId}/sites/{siteId}/population-target  — site default
GET      /orgs/{orgId}/menus/{id}/nutrition-check        — band-by-band analysis

Content library

GET  /orgs/{orgId}/content/packs
GET  /orgs/{orgId}/content/packs/{key}
POST /orgs/{orgId}/content/packs/{key}/install   — Pro+; {publish, includeMenus}

Installation clones the pack's recipes and cycle menus into the organization as editable records; it's idempotent — existing names are skipped.