# Recipe API — Complete API Reference > B2B Recipe API providing structured recipes with comprehensive nutrition data. - **Version:** 1.0.0 - **Base URL:** https://recipe-api.com - **Contact:** paul@recipe-api.com - **OpenAPI Spec:** https://recipe-api.com/openapi.json - **Quick start (no auth):** `curl https://recipe-api.com/api/v1/dinner` - **Get API Key:** https://recipe-api.com/auth/checkout?tier=free ## Authentication - **ApiKeyAuth:** apiKey via `X-API-Key` header header - API key in format `rapi_` ## Endpoints ## Public No authentication required. Try `/api/v1/dinner` for a complete recipe example. ### `GET /health` **Health check** - **Authentication:** No **Responses:** - **200:** Service is healthy **Response schema:** - **status** (string) (e.g. `"ok"`) - **timestamp** (string (date-time)) --- ### `GET /api/v1/dinner` **What's for dinner?** Returns a single delicious dinner recipe with all fields. Perfect for testing the API schema. Try it: `curl https://recipe-api.com/api/v1/dinner` - **Authentication:** No **Responses:** - **200:** A complete recipe **Response schema:** - **id** (string (uuid)) - **name** (string) - **description** (string) - **category** (string) - **cuisine** (string) - **difficulty** (string) - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **storage** (object) - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) - **equipment** (array of object) - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) - **ingredients** (array of object) - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) - **instructions** (array of object) - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) - **troubleshooting** (array of object) - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) - **chef_notes** (array of string) - **cultural_context** (string, nullable) - **nutrition** (object) - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) **Example response:** ```json { "id": "a066f472-ed0c-46ea-8e2c-a0053c3183a8", "name": "Texas Chili con Carne", "description": "A thick, beef-based stew featuring tender cubes of meat in a rich sauce made from reconstituted whole chilies and aromatic spices without beans or tomatoes.", "category": "Dinner", "cuisine": "American", "difficulty": "Intermediate", "tags": [ "Beef", "Slow-Cooked", "High-Protein", "Southwestern" ], "meta": { "active_time": "PT20M", "passive_time": "PT1H40M", "total_time": "PT2H", "overnight_required": false, "yields": "4 servings", "yield_count": 4, "serving_size_g": 300 }, "dietary": { "flags": [ "Gluten-Free", "Dairy-Free", "Egg-Free", "Nut-Free", "Soy-Free" ], "not_suitable_for": [] }, "storage": { "refrigerator": { "duration": "P4D", "notes": "Flavor improves after 24 hours." }, "freezer": { "duration": "P3M", "notes": "Thaw overnight in refrigerator before reheating." }, "reheating": "Heat in a saucepan over medium-low heat, adding a splash of water if too thick.", "does_not_keep": false }, "equipment": [ { "name": "Blender", "required": true, "alternative": "Food processor or mortar and pestle" }, { "name": "Heavy skillet", "required": true, "alternative": "Dutch oven" } ], "ingredients": [ { "group_name": "Chili Base", "items": [ { "name": "dried red chilies", "quantity": 6, "unit": null, "preparation": "stemmed and seeded", "notes": "about 30g", "substitutions": [ "ancho chilies", "guajillo chilies" ], "ingredient_id": "3c3f97d4-c951-43fd-865c-88fa8b445739", "nutrition_source": "USDA FoodData Central" }, { "name": "stewing beef", "quantity": 910, "unit": "g", "preparation": "cut into 1.3cm cubes", "notes": null, "substitutions": [], "ingredient_id": "09f2eef4-739a-4fca-8b63-97d697257990", "nutrition_source": "USDA FoodData Central" } ] }, { "group_name": "Flavor Paste", "items": [ { "name": "garlic", "quantity": 2, "unit": "cloves", "preparation": "peeled", "notes": null, "substitutions": [], "ingredient_id": "30109e1e-d8e8-4f76-a6f4-82ac5b071fde", "nutrition_source": "USDA FoodData Central" }, { "name": "cumin", "quantity": 7, "unit": "g", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "b9c9e3cb-61b7-4bbc-87c0-7858d42d7935", "nutrition_source": "USDA FoodData Central" } ] } ], "instructions": [ { "step_number": 1, "phase": "prep", "text": "Tear the dried chilies into strips and place them in a bowl. Cover with 240ml of boiling water and soak for 30 minutes.", "structured": { "action": "SOAK", "temperature": null, "duration": "PT30M", "doneness_cues": null }, "tips": [] }, { "step_number": 2, "phase": "cook", "text": "Heat olive oil in a heavy skillet over medium-high heat. Brown the beef cubes on all sides until a crust forms.", "structured": { "action": "SEAR", "temperature": null, "duration": null, "doneness_cues": { "visual": "Beef is deeply browned on all sides", "tactile": null } }, "tips": [] }, { "step_number": 3, "phase": "cook", "text": "Reduce heat to low, cover, and simmer for 1 hour until beef is fork-tender.", "structured": { "action": "SIMMER", "temperature": { "celsius": 90, "fahrenheit": 194 }, "duration": "PT1H", "doneness_cues": { "visual": null, "tactile": "Beef cubes are fork-tender" } }, "tips": [] } ], "troubleshooting": [ { "symptom": "Beef is tough or chewy", "likely_cause": "The meat has not simmered long enough.", "prevention": "Ensure liquid is at a very low simmer with lid sealed.", "fix": "Continue simmering in 15-minute increments until tender." } ], "chef_notes": [ "For deeper flavor, use a variety of dried chilies like ancho, guajillo, and pasilla." ], "cultural_context": "Texas Chili is a hearty stew deeply rooted in Texan culinary tradition, distinguished by the absence of beans and tomatoes.", "nutrition": { "per_serving": { "calories": 569, "protein_g": 44.1, "carbohydrates_g": 5.6, "fat_g": 42, "saturated_fat_g": 16.5, "fiber_g": 2, "sodium_mg": 351, "cholesterol_mg": 155, "potassium_mg": 903, "iron_mg": 7.2, "vitamin_b12_mcg": 6.1 }, "sources": [ "USDA FoodData Central" ] } } ``` --- ## Discovery Requires API key. No credit cost. Browse categories, cuisines, and dietary options. ### `GET /api/v1/categories` **List all categories** Returns all recipe categories with recipe counts. No credit cost. - **Authentication:** Yes **Responses:** - **200:** List of categories - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **name** (string) (e.g. `"Dinner"`) - **count** (integer) (e.g. `245`) **Example response:** ```json { "data": [ { "name": "Dinner", "count": 847 }, { "name": "Breakfast", "count": 312 }, { "name": "Lunch", "count": 289 }, { "name": "Dessert", "count": 256 }, { "name": "Appetizer", "count": 198 }, { "name": "Snack", "count": 145 }, { "name": "Brunch", "count": 89 }, { "name": "Side Dish", "count": 76 } ] } ``` --- ### `GET /api/v1/cuisines` **List all cuisines** Returns all cuisines with recipe counts. No credit cost. - **Authentication:** Yes **Responses:** - **200:** List of cuisines - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **name** (string) (e.g. `"Italian"`) - **count** (integer) (e.g. `89`) **Example response:** ```json { "data": [ { "name": "Italian", "count": 234 }, { "name": "Mexican", "count": 198 }, { "name": "American", "count": 187 }, { "name": "Asian", "count": 156 }, { "name": "Mediterranean", "count": 134 }, { "name": "French", "count": 98 }, { "name": "Indian", "count": 89 }, { "name": "Japanese", "count": 76 }, { "name": "Thai", "count": 65 }, { "name": "Greek", "count": 54 } ] } ``` --- ### `GET /api/v1/dietary-flags` **List all dietary flags** Returns all dietary flags with recipe counts. No credit cost. - **Authentication:** Yes **Responses:** - **200:** List of dietary flags - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **name** (string) (e.g. `"Vegetarian"`) - **count** (integer) (e.g. `156`) **Example response:** ```json { "data": [ { "name": "Gluten-Free", "count": 456 }, { "name": "Vegetarian", "count": 387 }, { "name": "Dairy-Free", "count": 312 }, { "name": "Vegan", "count": 234 }, { "name": "Nut-Free", "count": 198 }, { "name": "Low-Carb", "count": 167 }, { "name": "Egg-Free", "count": 145 }, { "name": "Soy-Free", "count": 123 }, { "name": "Paleo", "count": 89 }, { "name": "Keto", "count": 67 } ] } ``` --- ### `GET /api/v1/ingredients` **Browse ingredients** Returns a paginated list of ingredients with optional filtering by name or category. No credit cost. - **Authentication:** Yes **Parameters:** - `q` (string, optional) — Search by ingredient name - `category` (string, optional) — Filter by category - `page` (integer, optional, default: `1`) — Page number - `per_page` (integer, optional, default: `50`) — Results per page **Responses:** - **200:** Paginated ingredient list - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **id** (string (uuid)) — Unique ingredient identifier - **name** (string) (e.g. `"Chickpeas, canned, drained"`) - **category** (string) — One of 23 canonical categories (e.g. `"Legumes"`) - **source** (string) — Data source: USDA or Aggregated Public Sources (e.g. `"USDA"`) - **meta** (object) - **total** (integer) - **page** (integer) - **per_page** (integer) **Example response:** ```json { "data": [ { "id": "001764f3-4d44-4dbc-801b-0e4f094c756d", "name": "Chickpeas, canned, drained", "category": "Legumes", "source": "USDA" }, { "id": "0004d34a-afbe-4934-b94e-195e1602b23d", "name": "Spelt, cooked", "category": "Grains & Pasta", "source": "USDA" }, { "id": "0009da79-3cdb-4838-bdab-2e65ee0a9ccd", "name": "Nashi pear", "category": "Fruits", "source": "Aggregated Public Sources" } ], "meta": { "total": 10441, "page": 1, "per_page": 50 } } ``` --- ### `GET /api/v1/ingredient-categories` **List all ingredient categories** Returns all ingredient categories with counts. No credit cost. - **Authentication:** Yes **Responses:** - **200:** List of ingredient categories - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **name** (string) (e.g. `"Vegetables"`) - **count** (integer) (e.g. `1200`) **Example response:** ```json { "data": [ { "name": "Vegetables", "count": 1283 }, { "name": "Beef", "count": 995 }, { "name": "Baked Goods", "count": 617 }, { "name": "Beverages", "count": 555 }, { "name": "Prepared Foods", "count": 530 }, { "name": "Sauces & Condiments", "count": 512 }, { "name": "Lamb & Game", "count": 504 } ] } ``` --- ## Recipes Browse recipes free. Full recipe detail costs 1 credit. Sample data shown inline. ### `GET /api/v1/recipes` **Browse and search recipes** Returns a paginated list of recipes with optional filtering. Discovery limited to 500 recipes; use filters for larger catalogs. No credit cost. - **Authentication:** Yes **Parameters:** - `q` (string, optional) — Search by name or description - `category` (string, optional) — Filter by category - `cuisine` (string, optional) — Filter by cuisine - `difficulty` (string, optional, values: [`Easy`, `Intermediate`, `Advanced`]) — Filter by difficulty - `dietary` (string, optional) — Filter by dietary flags (comma-separated) - `min_calories` (number, optional) — Minimum calories per serving - `max_calories` (number, optional) — Maximum calories per serving - `min_protein` (number, optional) — Minimum protein (g) per serving - `max_protein` (number, optional) — Maximum protein (g) per serving - `min_carbs` (number, optional) — Minimum carbohydrates (g) per serving - `max_carbs` (number, optional) — Maximum carbohydrates (g) per serving - `min_fat` (number, optional) — Minimum fat (g) per serving - `max_fat` (number, optional) — Maximum fat (g) per serving - `ingredients` (string, optional) — Comma-separated ingredient UUIDs (returns recipes containing ALL specified ingredients) - `page` (integer, optional, default: `1`) — Page number (discovery limited to 500 total recipes) - `per_page` (integer, optional, default: `20`) — Results per page **Responses:** - **200:** Paginated recipe list - **400:** Discovery limit exceeded - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded **Response schema:** - **data** (array of object) - **id** (string (uuid)) - **name** (string) (e.g. `"Classic Margherita Pizza"`) - **description** (string) - **category** (string) (e.g. `"Dinner"`) - **cuisine** (string) (e.g. `"Italian"`) - **difficulty** (string) [`Easy`, `Intermediate`, `Advanced`] - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **nutrition_summary** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **meta** (object) - **total** (integer) — Total matching recipes (capped at 500 for discovery) - **page** (integer) - **per_page** (integer) - **total_capped** (boolean) — True if more recipes exist beyond the 500-recipe discovery limit **Example response:** ```json { "data": [ { "id": "a066f472-ed0c-46ea-8e2c-a0053c3183a8", "name": "Texas Chili con Carne", "description": "A thick, beef-based stew featuring tender cubes of meat in a rich sauce made from reconstituted whole chilies.", "category": "Dinner", "cuisine": "American", "difficulty": "Intermediate", "tags": [ "Beef", "Slow-Cooked", "High-Protein", "Southwestern" ], "meta": { "active_time": "PT20M", "passive_time": "PT1H40M", "total_time": "PT2H", "overnight_required": false, "yields": "4 servings", "yield_count": 4, "serving_size_g": 300 }, "dietary": { "flags": [ "Gluten-Free", "Dairy-Free", "Nut-Free" ], "not_suitable_for": [] }, "nutrition_summary": { "calories": 569, "protein_g": 44.1, "carbohydrates_g": 5.6, "fat_g": 42 } }, { "id": "b177e583-fe1d-57fb-9f3d-b1164d4294b9", "name": "Classic Margherita Pizza", "description": "Traditional Neapolitan pizza with San Marzano tomatoes, fresh mozzarella, basil, and olive oil on a thin, crispy crust.", "category": "Dinner", "cuisine": "Italian", "difficulty": "Easy", "tags": [ "Vegetarian", "Italian", "Quick" ], "meta": { "active_time": "PT25M", "passive_time": "PT1H", "total_time": "PT1H25M", "overnight_required": false, "yields": "2 pizzas", "yield_count": 2, "serving_size_g": 250 }, "dietary": { "flags": [ "Vegetarian", "Nut-Free" ], "not_suitable_for": [ "Lactose intolerant" ] }, "nutrition_summary": { "calories": 320, "protein_g": 14.5, "carbohydrates_g": 38.2, "fat_g": 12.8 } } ], "meta": { "total": 500, "page": 1, "per_page": 20, "total_capped": true } } ``` --- ### `GET /api/v1/recipes/{id}` **Get full recipe by ID** Returns complete recipe details including ingredients, instructions, and nutrition. **Costs 1 credit.** - **Authentication:** Yes **Parameters:** - `id` (string, required) — Recipe UUID **Responses:** - **200:** Full recipe details with usage info - **400:** Invalid request - **401:** Missing or invalid API key - **402:** Monthly credit limit exceeded - **403:** API key lacks permission - **404:** Resource not found **Response schema:** - **data** (object) - **id** (string (uuid)) - **name** (string) - **description** (string) - **category** (string) - **cuisine** (string) - **difficulty** (string) - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **storage** (object) - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) - **equipment** (array of object) - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) - **ingredients** (array of object) - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) - **instructions** (array of object) - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) - **troubleshooting** (array of object) - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) - **chef_notes** (array of string) - **cultural_context** (string, nullable) - **nutrition** (object) - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) - **usage** (object) — API usage information returned with each recipe fetch. Limits vary by plan: Free (50/day), Indie (200/day), Growth (500/day), Scale (2,000/day), Enterprise (50,000/day). - **monthly_remaining** (integer) — Requests remaining this billing period (e.g. `1950`) - **monthly_limit** (integer) — Total monthly quota (e.g. `2000`) - **daily_remaining** (integer) — Requests remaining today (e.g. `95`) - **daily_limit** (integer) — Maximum requests per day (e.g. `100`) **Example response:** ```json { "data": { "id": "a066f472-ed0c-46ea-8e2c-a0053c3183a8", "name": "Texas Chili con Carne", "description": "A thick, beef-based stew featuring tender cubes of meat in a rich sauce made from reconstituted whole chilies and aromatic spices without beans or tomatoes.", "category": "Dinner", "cuisine": "American", "difficulty": "Intermediate", "tags": [ "Beef", "Slow-Cooked", "High-Protein", "Southwestern" ], "meta": { "active_time": "PT20M", "passive_time": "PT1H40M", "total_time": "PT2H", "overnight_required": false, "yields": "4 servings", "yield_count": 4, "serving_size_g": 300 }, "dietary": { "flags": [ "Gluten-Free", "Dairy-Free", "Egg-Free", "Nut-Free", "Peanut-Free", "Soy-Free" ], "not_suitable_for": [] }, "storage": { "refrigerator": { "duration": "P4D", "notes": "Flavor improves after 24 hours." }, "freezer": { "duration": "P3M", "notes": "Thaw overnight in refrigerator before reheating." }, "reheating": "Heat in a saucepan over medium-low heat, adding a splash of water if too thick.", "does_not_keep": false }, "equipment": [ { "name": "Blender", "required": true, "alternative": "Food processor or mortar and pestle" }, { "name": "Heavy skillet", "required": true, "alternative": "Dutch oven or heavy-bottomed pot" }, { "name": "Mixing bowl", "required": true, "alternative": null } ], "ingredients": [ { "group_name": "Chili Base", "items": [ { "name": "red chilies", "quantity": 6, "unit": null, "preparation": "dried", "notes": "about 30g", "substitutions": [], "ingredient_id": "3c3f97d4-c951-43fd-865c-88fa8b445739", "nutrition_source": "USDA FoodData Central" }, { "name": "stewing beef", "quantity": 910, "unit": "g", "preparation": "cut into 1.3cm (1/2 inch) cubes", "notes": null, "substitutions": [], "ingredient_id": "09f2eef4-739a-4fca-8b63-97d697257990", "nutrition_source": "USDA FoodData Central" }, { "name": "olive oil", "quantity": 15, "unit": "ml", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "e9f370c4-07c8-4d8d-8a9f-0edea38db44c", "nutrition_source": "USDA FoodData Central" }, { "name": "bay leaves", "quantity": 2, "unit": null, "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "eab2ef3a-7a0e-4188-b746-645b795ada1e", "nutrition_source": "USDA FoodData Central" } ] }, { "group_name": "Flavor Paste", "items": [ { "name": "garlic", "quantity": 2, "unit": null, "preparation": "peeled", "notes": "about 6g", "substitutions": [], "ingredient_id": "30109e1e-d8e8-4f76-a6f4-82ac5b071fde", "nutrition_source": "USDA FoodData Central" }, { "name": "cumin", "quantity": 7, "unit": "g", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "b9c9e3cb-61b7-4bbc-87c0-7858d42d7935", "nutrition_source": "USDA FoodData Central" }, { "name": "oregano", "quantity": 3, "unit": "g", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "687f54eb-e811-4e5e-ac2e-e2735458480c", "nutrition_source": "USDA FoodData Central" }, { "name": "paprika", "quantity": 14, "unit": "g", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "f4c3bdd7-6528-40d2-84b3-a6325df15e8e", "nutrition_source": "USDA FoodData Central" }, { "name": "sugar", "quantity": 4, "unit": "g", "preparation": null, "notes": null, "substitutions": [], "ingredient_id": "8ae7f905-b311-4f45-9527-5e3840369506", "nutrition_source": "USDA FoodData Central" }, { "name": "salt", "quantity": null, "unit": null, "preparation": null, "notes": "to taste", "substitutions": [], "ingredient_id": "2631739c-2de4-4389-a6e3-ed3d06d0406f", "nutrition_source": "USDA FoodData Central" }, { "name": "black pepper", "quantity": null, "unit": null, "preparation": null, "notes": "to taste", "substitutions": [], "ingredient_id": "c25dc1c9-4ea7-403c-976e-ab1d06578b7a", "nutrition_source": "USDA FoodData Central" } ] } ], "instructions": [ { "step_number": 1, "phase": "prep", "text": "Tear the dried chilies into strips and place them in a bowl. Cover with 240ml (1 cup) of boiling water and soak for 30 minutes.", "structured": { "action": "SOAK", "temperature": null, "duration": "PT30M", "doneness_cues": null }, "tips": [] }, { "step_number": 2, "phase": "prep", "text": "Drain the chilies and set them aside. Reserve the soaking liquid for the cooking process.", "structured": { "action": "DRAIN", "temperature": null, "duration": null, "doneness_cues": null }, "tips": [] }, { "step_number": 3, "phase": "cook", "text": "Heat olive oil in a heavy skillet over medium-high heat. Brown the beef cubes on all sides until a crust forms.", "structured": { "action": "SEAR", "temperature": null, "duration": null, "doneness_cues": { "visual": "Beef is deeply browned on all sides", "tactile": null } }, "tips": [] }, { "step_number": 4, "phase": "cook", "text": "Pour the reserved chili soaking liquid into the skillet. Add bay leaves and bring the liquid to a boil.", "structured": { "action": "BOIL", "temperature": null, "duration": null, "doneness_cues": null }, "tips": [] }, { "step_number": 5, "phase": "cook", "text": "Reduce the heat to low, cover the skillet, and simmer for 1 hour.", "structured": { "action": "SIMMER", "temperature": { "celsius": 90, "fahrenheit": 194 }, "duration": "PT1H", "doneness_cues": null }, "tips": [] }, { "step_number": 6, "phase": "prep", "text": "Combine the soaked chilies, garlic, cumin, oregano, paprika, sugar, salt, and pepper in a blender. Puree until smooth, adding a small amount of fresh water if the mixture is too thick.", "structured": { "action": "PUREE", "temperature": null, "duration": null, "doneness_cues": null }, "tips": [] }, { "step_number": 7, "phase": "cook", "text": "Stir the chili puree into the skillet with the beef. Cover and continue to simmer for 30 minutes.", "structured": { "action": "SIMMER", "temperature": null, "duration": "PT30M", "doneness_cues": { "visual": null, "tactile": "Beef cubes are fork-tender" } }, "tips": [] }, { "step_number": 8, "phase": "finish", "text": "Remove and discard the bay leaves. Taste and add more salt or pepper if needed before serving.", "structured": { "action": "SERVE", "temperature": null, "duration": null, "doneness_cues": null }, "tips": [] } ], "troubleshooting": [ { "symptom": "Beef is tough or chewy", "likely_cause": "The meat has not simmered long enough to break down connective tissue.", "prevention": "Ensure the liquid is at a very low simmer and the lid is tightly sealed.", "fix": "Continue simmering in 15-minute increments until tender." }, { "symptom": "Chili is too watery", "likely_cause": "Too much water added during blending or insufficient reduction.", "prevention": "Add water to the blender only 15ml at a time.", "fix": "Simmer uncovered for the final 15 minutes to evaporate excess moisture." } ], "chef_notes": [ "For the deepest chili flavor, use a variety of dried chilies like ancho, guajillo, and pasilla. Toasting them briefly before soaking can enhance their aroma.", "Don't overcrowd the skillet when browning the beef; sear in batches if necessary to ensure a good crust, which adds significant flavor to the final dish.", "The simmering time is crucial for tenderizing the beef. Low and slow is key; the meat should be easily pierced with a fork.", "The consistency of the chili can be adjusted by the amount of soaking liquid you use and the final simmering time. If it's too thick, add a splash of water or beef broth; if too thin, simmer uncovered for a bit longer." ], "cultural_context": "Texas Chili, or Chili con Carne, is a hearty stew deeply rooted in Texan culinary tradition. Its origins trace back to the mid-19th century, with early versions featuring simple ingredients like dried beef, chilies, and spices, cooked by cowboys and ranchers. The absence of beans and tomatoes is a defining characteristic, distinguishing it from other regional chili variations and emphasizing its pure, meat-and-chili flavor profile.", "nutrition": { "per_serving": { "calories": 569.02, "protein_g": 44.14, "carbohydrates_g": 5.59, "fat_g": 41.99, "saturated_fat_g": 16.48, "trans_fat_g": 2.39, "monounsaturated_fat_g": 20.66, "polyunsaturated_fat_g": 2.29, "fiber_g": 1.97, "sugar_g": 1.84, "sodium_mg": 350.75, "cholesterol_mg": 154.7, "potassium_mg": 903.3, "calcium_mg": 74.24, "iron_mg": 7.16, "magnesium_mg": 60.57, "phosphorus_mg": 434.12, "zinc_mg": 16.82, "vitamin_a_mcg": 101.01, "vitamin_c_mg": 11.51, "vitamin_d_mcg": 0.23, "vitamin_e_mg": 2.15, "vitamin_k_mcg": 14.73, "vitamin_b6_mg": 0.97, "vitamin_b12_mcg": 6.14, "thiamin_mg": 0.19, "riboflavin_mg": 0.38, "niacin_mg": 10.47, "folate_mcg": 12.53, "water_g": 154.87, "alcohol_g": null, "caffeine_mg": null }, "sources": [ "USDA FoodData Central" ] } }, "usage": { "monthly_remaining": 1950, "monthly_limit": 2000, "daily_remaining": 95, "daily_limit": 100 } } ``` --- ### `POST /api/v1/generate` **Generate a recipe with nutrition** Creates a new recipe from structured constraints. Includes USDA-verified nutrition calculation. Requires generate credits (separate from request limits). - **Authentication:** Yes **Parameters:** - `dry_run` (boolean, optional) — Return usage and generated content without persisting. Only available when ENABLE_GENERATE_DRY_RUN=true. **Request Body:** Required fields: `title`, `key_ingredients`, `cuisine`, `difficulty`, `equipment`, `time` - **title** (string) - **key_ingredients** (array of string) - **cuisine** (string) - **difficulty** (string) [`Easy`, `Intermediate`, `Advanced`, `Professional`] - **equipment** (array of string) - **time** (integer) — Target total time in minutes - **notes** (string) **Example request:** ```json { "title": "Lemon Herb Chicken", "key_ingredients": [ "chicken breast", "lemon", "garlic", "olive oil" ], "cuisine": "Mediterranean", "difficulty": "Easy", "equipment": [ "skillet" ], "time": 35, "notes": "Weeknight-friendly, bright and zesty." } ``` **Responses:** - **201:** Generated recipe - **400:** Invalid request - **401:** Missing or invalid API key - **403:** API key lacks permission - **429:** Rate limit exceeded - **502:** Generation output invalid **Response schema:** - **data** (object) - **id** (string (uuid)) - **name** (string) - **description** (string) - **category** (string) - **cuisine** (string) - **difficulty** (string) - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **storage** (object) - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) - **equipment** (array of object) - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) - **ingredients** (array of object) - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) - **instructions** (array of object) - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) - **troubleshooting** (array of object) - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) - **chef_notes** (array of string) - **cultural_context** (string, nullable) - **nutrition** (object) - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) - **usage** (object) - **daily_remaining** (integer) — Generate credits remaining today - **daily_limit** (integer) — Daily generate credit limit - **monthly_remaining** (integer) — Generate credits remaining this month - **monthly_limit** (integer) — Monthly generate credit limit --- ## Data Schemas Complete type definitions for all objects returned by the API. ### RecipeListItem - **id** (string (uuid)) - **name** (string) (e.g. `"Classic Margherita Pizza"`) - **description** (string) - **category** (string) (e.g. `"Dinner"`) - **cuisine** (string) (e.g. `"Italian"`) - **difficulty** (string) [`Easy`, `Intermediate`, `Advanced`] - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **nutrition_summary** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) ### Recipe - **id** (string (uuid)) - **name** (string) - **description** (string) - **category** (string) - **cuisine** (string) - **difficulty** (string) - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **storage** (object) - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) - **equipment** (array of object) - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) - **ingredients** (array of object) - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) - **instructions** (array of object) - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) - **troubleshooting** (array of object) - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) - **chef_notes** (array of string) - **cultural_context** (string, nullable) - **nutrition** (object) - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) ### RecipeMeta Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) ### Dietary - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) ### Storage - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) ### Equipment - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) ### IngredientGroup - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) ### Ingredient - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) ### Instruction - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) ### StructuredStep - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) ### Troubleshooting - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) ### Nutrition - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) ### Error - **error** (object) - **code** (string) - **message** (string) ### Usage API usage information returned with each recipe fetch. Limits vary by plan: Free (50/day), Indie (200/day), Growth (500/day), Scale (2,000/day), Enterprise (50,000/day). - **monthly_remaining** (integer) — Requests remaining this billing period (e.g. `1950`) - **monthly_limit** (integer) — Total monthly quota (e.g. `2000`) - **daily_remaining** (integer) — Requests remaining today (e.g. `95`) - **daily_limit** (integer) — Maximum requests per day (e.g. `100`) ### IngredientItem An ingredient from the master ingredients database - **id** (string (uuid)) — Unique ingredient identifier - **name** (string) (e.g. `"Chickpeas, canned, drained"`) - **category** (string) — One of 23 canonical categories (e.g. `"Legumes"`) - **source** (string) — Data source: USDA or Aggregated Public Sources (e.g. `"USDA"`) ### GenerateRequest - **title** (string) - **key_ingredients** (array of string) - **cuisine** (string) - **difficulty** (string) [`Easy`, `Intermediate`, `Advanced`, `Professional`] - **equipment** (array of string) - **time** (integer) — Target total time in minutes - **notes** (string) **Required:** `title`, `key_ingredients`, `cuisine`, `difficulty`, `equipment`, `time` ### RecipeResponse Response from generate endpoint containing the created recipe and usage info - **data** (object) - **id** (string (uuid)) - **name** (string) - **description** (string) - **category** (string) - **cuisine** (string) - **difficulty** (string) - **tags** (array of string) - **meta** (object) — Timing and yield information - **active_time** (string) — ISO 8601 duration (e.g. `"PT45M"`) - **passive_time** (string) — ISO 8601 duration (e.g. `"PT30M"`) - **total_time** (string) — ISO 8601 duration (e.g. `"PT1H15M"`) - **overnight_required** (boolean) - **yields** (string) (e.g. `"4 servings"`) - **yield_count** (integer) (e.g. `4`) - **serving_size_g** (number, nullable) (e.g. `285`) - **dietary** (object) - **flags** (array of string) (e.g. `["Vegetarian","Gluten-Free"]`) - **not_suitable_for** (array of string) (e.g. `["Nut allergy"]`) - **storage** (object) - **refrigerator** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P3D"`) - **notes** (string) - **freezer** (object, nullable) - **duration** (string) — ISO 8601 duration (e.g. `"P2M"`) - **notes** (string) - **reheating** (string, nullable) - **does_not_keep** (boolean) - **equipment** (array of object) - **name** (string) (e.g. `"Stand mixer"`) - **required** (boolean) - **alternative** (string, nullable) (e.g. `"Hand mixer"`) - **ingredients** (array of object) - **group_name** (string) (e.g. `"For the dough"`) - **items** (array of object) - **name** (string) (e.g. `"all-purpose flour"`) - **quantity** (number, nullable) (e.g. `2.5`) - **unit** (string, nullable) (e.g. `"cups"`) - **preparation** (string, nullable) (e.g. `"sifted"`) - **notes** (string, nullable) - **substitutions** (array of string) - **ingredient_id** (string (uuid), nullable) - **nutrition_source** (string, nullable) (e.g. `"USDA FoodData Central"`) - **instructions** (array of object) - **step_number** (integer) - **phase** (string) — One of: prep, cook, assemble, finish (e.g. `"prep"`) - **text** (string) - **structured** (object, nullable) - **action** (string) (e.g. `"ROAST"`) - **temperature** (object, nullable) - **celsius** (integer) (e.g. `200`) - **fahrenheit** (integer) (e.g. `392`) - **duration** (string, nullable) — ISO 8601 duration (e.g. `"PT25M"`) - **doneness_cues** (object, nullable) - **visual** (string, nullable) (e.g. `"Golden brown edges"`) - **tactile** (string, nullable) (e.g. `"Springs back when pressed"`) - **tips** (array of string) - **troubleshooting** (array of object) - **symptom** (string) (e.g. `"Dough too sticky"`) - **likely_cause** (string) (e.g. `"Too much water or humidity"`) - **prevention** (string) (e.g. `"Add flour gradually, check humidity"`) - **fix** (string) (e.g. `"Dust with flour while kneading"`) - **chef_notes** (array of string) - **cultural_context** (string, nullable) - **nutrition** (object) - **per_serving** (object) - **calories** (number, nullable) - **protein_g** (number, nullable) - **carbohydrates_g** (number, nullable) - **fat_g** (number, nullable) - **saturated_fat_g** (number, nullable) - **trans_fat_g** (number, nullable) - **monounsaturated_fat_g** (number, nullable) - **polyunsaturated_fat_g** (number, nullable) - **fiber_g** (number, nullable) - **sugar_g** (number, nullable) - **sodium_mg** (number, nullable) - **cholesterol_mg** (number, nullable) - **potassium_mg** (number, nullable) - **calcium_mg** (number, nullable) - **iron_mg** (number, nullable) - **magnesium_mg** (number, nullable) - **phosphorus_mg** (number, nullable) - **zinc_mg** (number, nullable) - **vitamin_a_mcg** (number, nullable) - **vitamin_c_mg** (number, nullable) - **vitamin_d_mcg** (number, nullable) - **vitamin_e_mg** (number, nullable) - **vitamin_k_mcg** (number, nullable) - **vitamin_b6_mg** (number, nullable) - **vitamin_b12_mcg** (number, nullable) - **thiamin_mg** (number, nullable) - **riboflavin_mg** (number, nullable) - **niacin_mg** (number, nullable) - **folate_mcg** (number, nullable) - **water_g** (number, nullable) - **alcohol_g** (number, nullable) - **caffeine_mg** (number, nullable) - **sources** (array of string) (e.g. `["USDA FoodData Central"]`) - **usage** (object) - **daily_remaining** (integer) — Generate credits remaining today - **daily_limit** (integer) — Daily generate credit limit - **monthly_remaining** (integer) — Generate credits remaining this month - **monthly_limit** (integer) — Monthly generate credit limit ## Pricing & Rate Limits | Tier | Price | Requests/day | Unique Recipes/mo | Generate/day | Generate/mo | Rate/min | Caching Rights | |------|-------|-------------|-------------------|-------------|------------|---------|----------------| | Free | $0 | 100 | 25 | 0 | 0 | 10 | None | | Indie | $39/mo | 500 | 150 | 3 | 50 | 20 | 24-hour local | | Growth | $249/mo | 2,000 | 1,000 | 10 | 200 | 60 | 7-day local | | Scale | $999/mo | 10,000 | 5,000 | 25 | 500 | 300 | Permanent | | Enterprise | $4,999/mo | 100,000 | Unlimited | 100 | 2,000 | 1,000 | Unlimited + white-label | ## Error Codes All errors return `{ "error": { "code": "...", "message": "..." } }` | Code | HTTP | Description | |------|------|-------------| | UNAUTHORIZED | 401 | Missing or invalid API key | | FORBIDDEN | 403 | API key lacks permission for this endpoint | | BAD_REQUEST | 400 | Invalid parameters or request body | | NOT_FOUND | 404 | Recipe or resource not found | | RATE_LIMITED | 429 | Per-minute rate limit exceeded | | UNIQUE_RECIPE_LIMIT_EXCEEDED | 429 | Monthly unique recipe limit reached | | LIMIT_EXCEEDED | 402 | Monthly credit limit exceeded | | GENERATE_LIMIT_EXCEEDED | 429 | Daily or monthly generate limit reached | | DISCOVERY_LIMIT_EXCEEDED | 400 | Page exceeds 500-recipe discovery cap | | INVALID_RECIPE_OUTPUT | 502 | Generated recipe failed validation | | GENERATION_FAILED | 502 | Internal generation error | ## Notes for LLM Integration 1. All times use ISO 8601 duration format (PT30M = 30 minutes, P2D = 2 days) 2. Temperatures always include both Celsius and Fahrenheit 3. Nutrition is per-serving and USDA-sourced with 32 nutrient fields 4. Discovery endpoints (categories, cuisines, dietary-flags, ingredients) are free — no credit cost 5. Re-requesting the same recipe ID does not count against unique recipe limits 6. The `/api/v1/dinner` endpoint requires no authentication — use it to understand the schema 7. Generated recipes via `POST /api/v1/generate` return the exact same schema as retrieval endpoints