Skip to content

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  }
  ]
}
FieldTypeNotes
servingsinteger1–100. Divides total nutrition for per_serving
ingredientsarray1–50 items max
ingredients[].food_idintegerFrom /search/foods
ingredients[].gramsfloatWeight 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.

Get your free API key | Read the full docs

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.

← Back to all articles

Start building with the Calorie API

Get a free API key and access 4M+ foods with search, barcode lookup, and full macro data.