Prerequisites
You need three things:
- Python 3.8 or newer.
- The
requestslibrary. - A free API Ninjas API key — issued instantly, no credit card. If you already have an account, it's on your profile page.
pip install requestsStep 1: Look up your first food
The endpoint is /v1/nutrition and takes one parameter: query, a natural-language description of the food:
import requests
response = requests.get(
'https://api.api-ninjas.com/v1/nutrition',
params={'query': '1 large apple'},
headers={'X-Api-Key': 'YOUR_API_KEY'},
timeout=10,
)
response.raise_for_status()
items = response.json()
for item in items:
print(f"{item['name']}: {item['carbohydrates_total_g']}g carbs, {item['sugar_g']}g sugar")
# apple: 25.6g carbs, 18.8g sugarThe request on the wire and the response (free-plan fields shown):
[
{
"name": "apple",
"serving_size_g": 182,
"fat_total_g": 0.3,
"fat_saturated_g": 0.1,
"fat_trans_g": 0,
"sodium_mg": 1,
"cholesterol_mg": 0,
"carbohydrates_total_g": 25.6,
"fiber_g": 4.3,
"sugar_g": 18.8
}
]Step 2: Read the response
The response is always a list, one entry per recognized food — because a single query can name several. Each entry carries the parsed serving_size_g, carbohydrates, sugar, fiber and fat in grams (carbohydrates_total_g, sugar_g, fiber_g, fat_total_g, fat_saturated_g), and minerals in milligrams (sodium_mg, cholesterol_mg). Note the quantity handling in the sample above: “1 large apple” became a 182-gram serving, and every value is scaled to it.
Paid plans also return calories, protein_g and a full set of micronutrients, plus food images; see the Nutrition API docs for every field.
Wrapped as a reusable client with the key in an environment variable:
import os
import requests
API_URL = 'https://api.api-ninjas.com/v1/nutrition'
session = requests.Session()
session.headers['X-Api-Key'] = os.environ.get('API_NINJAS_KEY', 'YOUR_API_KEY')
def get_nutrition(query: str) -> list:
"""Return nutrition data for a natural-language food query."""
response = session.get(API_URL, params={'query': query}, timeout=10)
response.raise_for_status()
return response.json()
for item in get_nutrition('200g chicken breast'):
print(f"{item['name']}: {item['fat_total_g']}g fat, {item['sodium_mg']}mg sodium")Step 3: Query in plain English
The query parser is the reason this API is pleasant to build on: it understands cups, grams, slices, and multiple foods joined with “and” — so user input can go straight through:
queries = [
'1 cup of rice',
'200g chicken breast',
'a slice of cheese pizza',
'1 banana and 2 tablespoons of peanut butter',
]
for q in queries:
items = get_nutrition(q)
carbs = sum(item['carbohydrates_total_g'] or 0 for item in items)
print(f'{q:45} {carbs:>6.1f}g carbs ({len(items)} item(s))')Step 4: Build a meal tracker
A meal is just a multi-food query, so totals are a sum over the returned list. This helper aggregates carbs, sugar, fiber, fat and sodium:
TRACKED = ['carbohydrates_total_g', 'sugar_g', 'fiber_g', 'fat_total_g', 'sodium_mg']
def meal_totals(query: str) -> dict:
"""Sum carbs, sugar, fiber, fat and sodium across every food in one query."""
totals = dict.fromkeys(TRACKED, 0.0)
for item in get_nutrition(query):
for key in TRACKED:
totals[key] += item.get(key) or 0
return totals
meal = meal_totals('2 eggs, 1 slice of toast, and 1 cup of orange juice')
print(f"Carbs: {meal['carbohydrates_total_g']:.1f} g") # 40.6 g
print(f"Sugar: {meal['sugar_g']:.1f} g") # 22.4 g
print(f"Fiber: {meal['fiber_g']:.1f} g") # 1.3 g
print(f"Fat: {meal['fat_total_g']:.1f} g") # 10.6 g
print(f"Sodium: {meal['sodium_mg']:.0f} mg") # 266 mgLog the totals to a CSV or SQLite table with a date column and you have a personal food diary in an afternoon.
Step 5: Handle errors
When no food is recognized, the API returns an empty list rather than an HTTP error. Check for it separately from the usual auth and rate-limit failures:
from requests.exceptions import HTTPError, RequestException
items = get_nutrition('flurbles') # unknown food
if not items:
print('No foods recognized — rephrase the query')
try:
items = get_nutrition('1 cup of rice')
except HTTPError as error:
status = error.response.status_code
if status == 401:
print('Missing or invalid API key')
elif status == 429:
print('Rate limit exceeded — slow down and retry')
else:
print(f'HTTP {status}: {error.response.text}')
except RequestException as error:
print(f'Network error: {error}')Where to go from here
For a fitness app, pair this with the Calories Burned API (the expenditure side of the ledger) and the Exercises API; for meal ideas, the Recipe API searches by ingredient. The complete command-line tracker is below.