Skip to content
Skip to Content
Docs
Studio

Set Recipe Ingredients

④ of 5 | Requires: ③ createRecipe | Next: ⑤ addRecipeServing

Save the full ingredient list for a recipe in one commit — add, edit, delete, and reorder are all expressed as the complete ordered list you send. Each item is a structured form or resolution row; there is no free-text parsing on this path.

The list is discriminated by source: • form — a structured search → pick → quantity row. Omit id for a new row (the server mints one) or send an existing irow_... id to edit/reorder it. • resolution — an existing row born from the resolve workflow. It must carry an existing irow_... id; immutable lineage is inherited server-side and cannot be supplied by the client.

ingredients_entry_method must equal the recipe's locked entry method. A recipe locked to form rejects any resolution row.

position is taken verbatim, so drag-reorder is a resend with the new positions. An empty items list deletes all ingredients.

On success, recipe-level nutrition (L1) and any existing per-serving panels (L2) are recomputed atomically in the same commit.

Next: ⑤ addRecipeServing — add a serving size to generate the final nutrition facts label.

POST
/studio/recipes/{recipe_id}/ingredients

Path Parameters

recipe_id*Recipe Id

Header Parameters

If-Match*string

The recipe's current version_id: the one the last change to this recipe returned, or the one reading the recipe returns (get_recipe). A stale value is refused with the current version_id; read the recipe again and retry.

Request Body

application/json
  1. body

Full-list save: add / edit / delete / reorder in one commit.

ingredients_entry_method*Ingredients Entry Method

Must equal the recipe's locked entry method.

Value in"resolution""form"
items*array<||>

The complete ordered ingredient list (empty = delete all).

Items0 <= items

Response Body

Successful Response

application/json
  1. response

Response for update ingredients endpoint.

data*

Data payload for update ingredients response.

meta*

Response metadata.

version_id?|

Version committed for this mutation; pass on the next request as If-Match for optimistic concurrency. Present only on versions declaring the recipe_versioning capability.

Example Request
curl -X POST 'https://api.bettermenu.live/studio/recipes/string/ingredients' \  -H 'If-Match: string' \  -H 'Content-Type: application/json' \  -d '{  "ingredients_entry_method": "resolution",  "items": []}'
Example Response
{  "data": {    "recipe_id": "string",    "resolution_id": "string",    "ingredients": [      {        "id": "string",        "position": 0,        "selected_ingredient_id": "string",        "selected_ingredient_name": "string",        "display_name": "string",        "metric_quantity_g": 0,        "search_provenance": "system_matched",        "unit_conversion_provenance": "identity",        "source": "resolution",        "original_text": "string",        "parsed_quantity": 0,        "parsed_unit": "string",        "parsed_ingredient_name": "string",        "portion_id": "string"      }    ],    "ingredient_conversions": [      {        "conversion_source": "string",        "reasoning": "string",        "portion_reference": {          "portion_bmid": "string",          "measure_unit_name": "string",          "gram_weight": "string",          "amount": "string"        }      }    ],    "ingredient_resolutions": [      {        "original_text": "string",        "parsed": {          "quantity_text": "string",          "quantity": 0,          "unit": "string",          "ingredient_name": "string"        },        "converted": {          "quantity": 0,          "unit": "string",          "steps": [            {              "from_quantity": 0,              "from_unit": "string",              "to_quantity": 0,              "to_unit": "string",              "source": "string",              "reasoning": "string"            }          ]        },        "matches": {          "query_text": "string",          "candidates": [            {              "ingredient_id": "string",              "ingredient_name": "string"            }          ],          "selected_match": {            "ingredient_id": "string",            "ingredient_name": "string"          },          "match_confidence": 0,          "search_strategy_used": "standard"        }      }    ],    "updated_at": "string"  },  "meta": {    "version": "string",    "request_id": "string",    "timestamp": "string"  },  "version_id": "string"}

Recipe in, FDA-format Nutrition Facts out, with every version kept.

Start freeNo card needed.