Recipe Nutrition Analyzer API: Get Total and Per-Serving Macros in One Request
Published June 16, 2026
A recipe nutrition analyzer API accepts a list of ingredients (food IDs and gram amounts) and returns aggregated total and per-serving nutrition for the full recipe; calories, protein, carbohydrates, fat, fiber, and sugars; in a single request. Instead of fetching each ingredient's nutrition separately, scaling by grams, and summing across every field in your frontend, you send one POST request and get a clean, ready-to-display nutrition object back.
This is Calorie API's POST /calc/recipe endpoint, purpose-built for recipe apps, meal prep planners, nutrition coaches, and food bloggers who need accurate macro breakdowns on multi-ingredient dishes.
The Endpoint
POST /api/v1/public/calc/recipe
Content-Type: application/json
Request body:
{
"servings": 4,
"ingredients": [
{ "food_id": 11420, "grams": 300 },
{ "food_id": 9200, "grams": 150 },
{ "food_id": 4053, "grams": 30 }
]
}
| Field | Type | Notes |
|---|---|---|
servings | integer | 1–100. Divides total nutrition for per_serving |
ingredients | array | 1–50 items max |
ingredients[].food_id | integer | From /search/foods |
ingredients[].grams | float | Weight of this ingredient in grams |
Quick Start
curl -X POST "https://api.calorieapi.com/api/v1/public/calc/recipe" \
-H "Content-Type: application/json" \
-d '{
"servings": 4,
"ingredients": [
{ "food_id": 11420, "grams": 300 },
{ "food_id": 9200, "grams": 150 },
{ "food_id": 4053, "grams": 30 }
]
}'
Response:
{
"servings": 4,
"total": {
"calories": 620.40,
"protein_g": 52.30,
"carbohydrates_g": 68.10,
"fat_g": 14.80,
"fiber_g": 9.20,
"sugars_g": 11.40
},
"per_serving": {
"calories": 155.10,
"protein_g": 13.08,
"carbohydrates_g": 17.03,
"fat_g": 3.70,
"fiber_g": 2.30,
"sugars_g": 2.85
},
"ingredients_resolved": 3
}
The ingredients_resolved field tells you how many ingredient IDs were found in the database — useful for catching stale or invalid food IDs without a 4xx error.
Step-by-Step Integration
Step 1: Resolve ingredient names to food IDs
Your recipe form likely takes ingredient names, not IDs. Run a search call for each ingredient and let the user confirm the best match:
async function resolveIngredient(name) {
const res = await fetch(
`https://api.calorieapi.com/api/v1/public/search/foods?q=${encodeURIComponent(name)}&limit=5`
)
const { data } = await res.json()
return data // show user a pick-list
}
Step 2: Collect the ingredient list
const ingredients = confirmedItems.map(item => ({
food_id: item.id,
grams: item.grams,
}))
Step 3: Call the recipe endpoint
async function analyzeRecipe(ingredients, servings) {
const res = await fetch('https://api.calorieapi.com/api/v1/public/calc/recipe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ servings, ingredients }),
})
if (!res.ok) throw new Error(`Recipe analysis failed: ${res.status}`)
return res.json()
}
Step 4: Render total and per-serving
function RecipeNutritionLabel({ result }) {
const s = result.per_serving
return (
<table>
<tbody>
<tr><td>Calories</td><td>{s.calories} kcal</td></tr>
<tr><td>Protein</td><td>{s.protein_g} g</td></tr>
<tr><td>Carbohydrates</td><td>{s.carbohydrates_g} g</td></tr>
<tr><td>Fat</td><td>{s.fat_g} g</td></tr>
<tr><td>Fiber</td><td>{s.fiber_g} g</td></tr>
</tbody>
</table>
)
}
Handling Missing Ingredients
If an ingredient food ID is not found in the database, it is silently skipped and ingredients_resolved will be less than ingredients.length. Check this field after every call:
if (result.ingredients_resolved < ingredients.length) {
const missing = ingredients.length - result.ingredients_resolved
console.warn(`${missing} ingredient(s) were not found and excluded from totals.`)
}
This is intentional: it avoids a 404 error for a single unknown food breaking the entire recipe analysis.
Use Cases
Recipe blog nutrition labels
Add an automatic nutrition label to every recipe on your food blog. Scrape or enter ingredients once; call the API on publish to store the totals alongside the post.
import httpx
def label_recipe(ingredients_with_grams: list[dict], servings: int) -> dict:
r = httpx.post(
"https://api.calorieapi.com/api/v1/public/calc/recipe",
json={"servings": servings, "ingredients": ingredients_with_grams},
)
r.raise_for_status()
return r.json()["per_serving"]
Meal prep apps
Users build a batch recipe (e.g., 5-day chicken and rice prep for 5 servings). The endpoint returns per-serving totals they can log as a single entry each day.
Diet coaching platforms
Coaches build custom meal plans with precise macro targets. The recipe analyzer confirms whether a combination of ingredients hits a client's protein and calorie goals before the plan is sent.
Grocery and cooking apps
Show a live "nutrition estimate" panel as the user adds ingredients to a recipe builder. Re-call the endpoint on every ingredient change.
Performance Tips
- Debounce live updates: Call the endpoint 500 ms after the last ingredient change, not on every keystroke.
- Cache resolved food IDs: Once a user picks "chicken breast, raw → food_id 12345", store that mapping so repeat lookups skip the search step.
- Pre-validate IDs: If you store food IDs in your own database, validate them against the
/foods/{id}endpoint periodically to catch any that have been removed.
Try It Without Code
Open the API Playground, select Recipe analyzer, edit the JSON body with your own food IDs and gram amounts, and click Send request.
Related Guides
Frequently Asked Questions
What is a recipe nutrition analyzer API?
It accepts a list of food IDs and gram amounts and returns aggregated calories, protein, carbohydrates, fat, fiber, and sugars for the full recipe plus a per-serving breakdown.
How do I get food IDs to use in the recipe endpoint?
Search for each ingredient using GET /search/foods, let the user confirm the best match, and store the id field. Pass those IDs with gram amounts in the POST body.
What happens if one ingredient ID is not found?
That ingredient is skipped and the ingredients_resolved count in the response will be less than the number submitted. Totals are calculated from the ingredients that were found.
How many ingredients can I include per request?
Up to 50 ingredients per request. For larger recipes, split into two requests and sum the totals in your application.
Can I use this endpoint to generate nutrition labels for a food blog?
Yes. Resolve the ingredient IDs once at recipe creation time, then call POST /calc/recipe to store per-serving nutrition alongside the recipe. Re-run when ingredients change.
