Nutrola's Nutrition Data API: How Developers Can Access Our Food Database
A developer guide to Nutrola's Nutrition Data API. Learn how to access our verified food database with over 3 million entries, explore endpoints, authentication, and real-world use cases.
Building a health, fitness, or food-related app? One of the hardest problems you will face is nutrition data. You need accurate calorie and macro information for thousands of foods, you need it to cover international products, and you need it to stay current as manufacturers reformulate their products.
Most developers start by pulling data from open government databases like USDA FoodData Central. That gives you a foundation, but it does not cover branded products from 47 countries, restaurant meals, or the thousands of regional foods that real users eat every day. Filling those gaps yourself means years of data curation work.
Nutrola's Nutrition Data API gives developers access to the same verified food database that powers our app — over 3 million entries, covering raw ingredients, branded products, restaurant meals, and composite recipes. Every entry is verified through our multi-layer quality control process, the same system trusted by over 2 million users.
This guide covers everything you need to know to start building with our API: architecture, authentication, endpoints, rate limits, and real-world code examples.
API Overview
The Nutrola Nutrition Data API is a RESTful JSON API. You make HTTP requests, you get JSON responses. No SDKs required, though we provide client libraries for Python, JavaScript, and Swift for convenience.
Base URL
https://api.nutrola.com/v1
All endpoints are served over HTTPS. Plain HTTP requests are rejected.
Key Capabilities
| Capability | Description |
|---|---|
| Food Search | Full-text search across 3M+ food entries with filtering by category, brand, and country |
| Barcode Lookup | Get nutrition data by UPC, EAN, or other barcode formats |
| Nutrition Details | Complete nutrition profile for any food (70+ nutrients including micros) |
| Serving Sizes | Standard and alternative serving sizes with gram conversions |
| Recipe Analysis | Submit a list of ingredients and get combined nutrition data |
| Food Categories | Browse the hierarchical food category taxonomy |
| Brand Directory | Search and browse branded food manufacturers |
| Autocomplete | Fast type-ahead suggestions for food search interfaces |
Response Format
All responses follow a consistent structure:
{
"status": "success",
"data": { },
"meta": {
"request_id": "req_abc123",
"rate_limit_remaining": 245,
"rate_limit_reset": "2026-03-10T15:00:00Z"
}
}
Error responses include a machine-readable error code and a human-readable message:
{
"status": "error",
"error": {
"code": "FOOD_NOT_FOUND",
"message": "No food entry matches the provided ID.",
"request_id": "req_xyz789"
}
}
Authentication
All API requests require an API key passed in the Authorization header.
Getting an API Key
- Create a developer account at developer.nutrola.com
- Navigate to the API Keys section in your dashboard
- Generate a new key and specify the scopes you need
- Store the key securely — it will only be displayed once
Using Your API Key
Include the key in every request header:
Authorization: Bearer YOUR_API_KEY
Example with curl:
curl -H "Authorization: Bearer ntr_live_abc123def456" \
https://api.nutrola.com/v1/foods/search?q=chicken+breast
API Key Scopes
| Scope | Access Level |
|---|---|
foods:read |
Search and retrieve food data (most common) |
barcodes:read |
Barcode lookup |
recipes:analyze |
Recipe nutrition analysis |
brands:read |
Brand directory access |
categories:read |
Food category taxonomy |
Keys can be scoped to specific capabilities. A key with only foods:read cannot access barcode lookups. This follows the principle of least privilege — request only the scopes your application needs.
Core Endpoints
Food Search
Search the database by name, keyword, or phrase.
GET /v1/foods/search
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes | Search query (e.g., "grilled chicken breast") |
category |
string | No | Filter by food category (e.g., "dairy", "vegetables") |
brand |
string | No | Filter by brand name |
country |
string | No | ISO 3166-1 alpha-2 country code (e.g., "US", "DE", "JP") |
verified_only |
boolean | No | Only return entries with verified source data (default: true) |
page |
integer | No | Page number for pagination (default: 1) |
per_page |
integer | No | Results per page, max 50 (default: 20) |
Example Request:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.nutrola.com/v1/foods/search?q=greek+yogurt&country=US&per_page=5"
Example Response:
{
"status": "success",
"data": {
"results": [
{
"id": "food_8f2k9d",
"name": "Greek Yogurt, Plain, Nonfat",
"brand": null,
"category": "dairy",
"country": "US",
"verified": true,
"source": "USDA",
"nutrition_per_100g": {
"calories": 59,
"protein": 10.2,
"carbohydrates": 3.6,
"fat": 0.4,
"fiber": 0,
"sugar": 3.2,
"sodium": 36
},
"default_serving": {
"description": "1 container (170g)",
"grams": 170
}
}
],
"total_results": 342,
"page": 1,
"per_page": 5
}
}
Get Food Details
Retrieve the complete nutrition profile for a specific food.
GET /v1/foods/{food_id}
Example Request:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.nutrola.com/v1/foods/food_8f2k9d"
The detail response includes the full nutrient breakdown — over 70 nutrients including all vitamins, minerals, amino acids, and fatty acid profiles. It also includes all available serving sizes and their gram equivalents.
Partial Response (Key Nutrients):
{
"status": "success",
"data": {
"id": "food_8f2k9d",
"name": "Greek Yogurt, Plain, Nonfat",
"nutrition_per_100g": {
"calories": 59,
"protein": 10.2,
"carbohydrates": 3.6,
"fat": 0.4,
"fiber": 0,
"sugar": 3.2,
"saturated_fat": 0.1,
"monounsaturated_fat": 0.1,
"polyunsaturated_fat": 0,
"cholesterol": 5,
"sodium": 36,
"potassium": 141,
"calcium": 110,
"iron": 0.1,
"vitamin_a": 4,
"vitamin_c": 0,
"vitamin_d": 0
},
"serving_sizes": [
{ "description": "1 container (170g)", "grams": 170 },
{ "description": "1 cup (245g)", "grams": 245 },
{ "description": "1 tbsp (15g)", "grams": 15 },
{ "description": "100g", "grams": 100 }
],
"allergens": ["milk"],
"source": "USDA",
"source_id": "170903",
"last_verified": "2026-02-15",
"confidence_score": 0.98
}
}
Barcode Lookup
Look up a food product by its barcode.
GET /v1/barcodes/{barcode}
Supported Formats: UPC-A, UPC-E, EAN-13, EAN-8
Example Request:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.nutrola.com/v1/barcodes/0049000006346"
The response returns the same food detail object as the /foods/{food_id} endpoint, with additional barcode-specific fields like barcode_format and regional_variants (an array of food IDs for the same product in different countries, which may have different formulations).
Recipe Analysis
Submit a list of ingredients and receive the combined nutrition breakdown.
POST /v1/recipes/analyze
Request Body:
{
"name": "Overnight Oats",
"servings": 2,
"ingredients": [
{ "food_id": "food_3k8m2n", "grams": 160 },
{ "food_id": "food_9p4q7r", "grams": 400 },
{ "food_id": "food_1a5b8c", "grams": 60 },
{ "food_id": "food_6d2e9f", "grams": 2, "description": "pinch of salt" }
]
}
You can also submit ingredients as text for automatic parsing:
{
"name": "Overnight Oats",
"servings": 2,
"ingredients_text": "160g rolled oats, 400ml whole milk, 60g peanut butter, pinch of salt"
}
Response:
{
"status": "success",
"data": {
"name": "Overnight Oats",
"servings": 2,
"nutrition_per_serving": {
"calories": 425,
"protein": 18.5,
"carbohydrates": 42.3,
"fat": 21.2,
"fiber": 5.8
},
"nutrition_total": {
"calories": 850,
"protein": 37.0,
"carbohydrates": 84.6,
"fat": 42.4,
"fiber": 11.6
},
"ingredients_matched": [
{ "input": "160g rolled oats", "matched_food": "food_3k8m2n", "confidence": 0.97 },
{ "input": "400ml whole milk", "matched_food": "food_9p4q7r", "confidence": 0.99 },
{ "input": "60g peanut butter", "matched_food": "food_1a5b8c", "confidence": 0.96 },
{ "input": "pinch of salt", "matched_food": "food_6d2e9f", "confidence": 0.88 }
]
}
}
Autocomplete
Fast type-ahead suggestions for building search interfaces.
GET /v1/foods/autocomplete?q={query}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes | Partial search query (minimum 2 characters) |
limit |
integer | No | Max results, 1-10 (default: 5) |
country |
string | No | Prioritize results from this country |
Response times are optimized for interactive use — typically under 50ms. The autocomplete endpoint returns simplified food objects (ID, name, brand, and category only) for fast rendering.
Rate Limits and Pricing
Free Tier
The free tier is designed for development, testing, and small-scale applications:
| Limit | Value |
|---|---|
| Requests per day | 500 |
| Requests per minute | 30 |
| Food search results per request | 20 |
| Recipe analysis per day | 10 |
| Barcode lookups per day | 100 |
Growth Tier
For production applications with moderate traffic:
| Limit | Value |
|---|---|
| Requests per day | 25,000 |
| Requests per minute | 300 |
| Food search results per request | 50 |
| Recipe analysis per day | 500 |
| Barcode lookups per day | 5,000 |
| Price | $49/month |
Enterprise Tier
For high-traffic applications, white-label solutions, and custom requirements:
| Feature | Details |
|---|---|
| Requests per day | Custom (typically 100K+) |
| Rate limits | Custom |
| Dedicated support | Included |
| SLA | 99.9% uptime guarantee |
| Custom data exports | Available |
| Webhook notifications | Available for data updates |
| Price | Contact sales |
Rate limit information is included in every API response via the meta object and in HTTP response headers (X-RateLimit-Remaining, X-RateLimit-Reset).
Real-World Use Cases
Fitness and Workout Apps
If you are building a fitness app and want to add nutrition tracking without building a food database from scratch, Nutrola's API is the fastest path. Use the food search and barcode endpoints to let users log meals, and the recipe analysis endpoint for custom meal entries.
Meal Planning Platforms
Meal planning apps need accurate nutrition data to generate plans that hit specific macro targets. The API's detailed nutrient breakdown (70+ nutrients) enables precise meal plan optimization, not just calories and macros but micronutrients, allergens, and dietary restriction compatibility.
Healthcare and Telehealth
Healthcare platforms that monitor patient nutrition can integrate with the API to provide accurate food logging within their existing interfaces. The verified data sources (USDA, EFSA, manufacturer-direct) meet the accuracy standards required for clinical nutrition monitoring.
Restaurant and Food Service
Restaurant ordering platforms can use the API to display nutrition information for menu items. The recipe analysis endpoint is particularly useful here — submit a dish's ingredients and get the complete nutrition breakdown without manually calculating each item.
Research and Academia
Nutrition researchers can use the API to standardize food coding in dietary studies. The consistent, verified data reduces the measurement error that plagues studies relying on participant-reported nutrition data.
Code Examples
Python: Search for a Food and Get Nutrition Details
import requests
API_KEY = "ntr_live_your_key_here"
BASE_URL = "https://api.nutrola.com/v1"
headers = {
"Authorization": f"Bearer {API_KEY}"
}
# Search for a food
search_response = requests.get(
f"{BASE_URL}/foods/search",
headers=headers,
params={"q": "chicken breast grilled", "per_page": 3}
)
results = search_response.json()["data"]["results"]
for food in results:
print(f"{food['name']} - {food['nutrition_per_100g']['calories']} cal/100g")
# Get full details for the first result
food_id = results[0]["id"]
detail_response = requests.get(
f"{BASE_URL}/foods/{food_id}",
headers=headers
)
food_detail = detail_response.json()["data"]
nutrition = food_detail["nutrition_per_100g"]
print(f"\n{food_detail['name']}")
print(f"Calories: {nutrition['calories']}")
print(f"Protein: {nutrition['protein']}g")
print(f"Carbs: {nutrition['carbohydrates']}g")
print(f"Fat: {nutrition['fat']}g")
print(f"Serving sizes: {food_detail['serving_sizes']}")
JavaScript: Barcode Scanning Integration
const API_KEY = "ntr_live_your_key_here";
const BASE_URL = "https://api.nutrola.com/v1";
async function lookupBarcode(barcode) {
const response = await fetch(
`${BASE_URL}/barcodes/${barcode}`,
{
headers: {
"Authorization": `Bearer ${API_KEY}`
}
}
);
if (!response.ok) {
if (response.status === 404) {
console.log("Product not found in database");
return null;
}
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return data.data;
}
// Example usage
const product = await lookupBarcode("0049000006346");
if (product) {
const serving = product.default_serving;
const factor = serving.grams / 100;
console.log(`${product.name} (${product.brand})`);
console.log(`Per ${serving.description}:`);
console.log(` Calories: ${Math.round(product.nutrition_per_100g.calories * factor)}`);
console.log(` Protein: ${(product.nutrition_per_100g.protein * factor).toFixed(1)}g`);
console.log(` Carbs: ${(product.nutrition_per_100g.carbohydrates * factor).toFixed(1)}g`);
console.log(` Fat: ${(product.nutrition_per_100g.fat * factor).toFixed(1)}g`);
}
Swift: Building an Autocomplete Search Field
import Foundation
class NutrolaAPI {
private let apiKey: String
private let baseURL = "https://api.nutrola.com/v1"
init(apiKey: String) {
self.apiKey = apiKey
}
func autocomplete(query: String, limit: Int = 5) async throws -> [FoodSuggestion] {
guard query.count >= 2 else { return [] }
var components = URLComponents(string: "\(baseURL)/foods/autocomplete")!
components.queryItems = [
URLQueryItem(name: "q", value: query),
URLQueryItem(name: "limit", value: String(limit))
]
var request = URLRequest(url: components.url!)
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
let response = try JSONDecoder().decode(AutocompleteResponse.self, from: data)
return response.data.suggestions
}
}
struct FoodSuggestion: Codable {
let id: String
let name: String
let brand: String?
let category: String
}
struct AutocompleteResponse: Codable {
let status: String
let data: AutocompleteData
}
struct AutocompleteData: Codable {
let suggestions: [FoodSuggestion]
}
Error Handling Best Practices
The API uses standard HTTP status codes:
| Status Code | Meaning | Common Cause |
|---|---|---|
| 200 | Success | Request completed normally |
| 400 | Bad Request | Missing required parameter or invalid value |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | API key lacks required scope |
| 404 | Not Found | Food ID or barcode not in database |
| 429 | Rate Limited | Too many requests; check rate limit headers |
| 500 | Server Error | Internal error; retry with exponential backoff |
When you receive a 429 response, the Retry-After header tells you how many seconds to wait before retrying. Implementing exponential backoff for 429 and 500 responses is strongly recommended for production applications.
Data Freshness and Updates
Nutrola's database is updated continuously. Branded product entries are refreshed when manufacturers report changes, typically within 48 hours. Government database entries are synchronized quarterly when new releases are published.
If your application caches API responses (which we recommend for performance), we suggest a cache TTL of 24 hours for food detail responses and 1 hour for search results. The last_verified field in food detail responses tells you when the entry was last confirmed accurate.
For enterprise customers, we offer webhook notifications when food entries are updated, so your application can invalidate cached data proactively rather than waiting for the cache TTL to expire.
Getting Started
- Sign up at developer.nutrola.com — it takes under a minute
- Generate an API key with the scopes you need
- Make your first request using the curl examples above
- Explore the interactive docs at developer.nutrola.com/docs where you can test endpoints directly in your browser
- Join the developer community on our Discord server for support, feature requests, and to see what other developers are building
If you have questions, encounter issues, or want to discuss an enterprise integration, reach out to our developer relations team at api@nutrola.com.
FAQ
Is the Nutrola API free to use?
Yes, there is a free tier that includes 500 requests per day. This is suitable for development, testing, and small-scale applications. For production applications with higher traffic, the Growth tier starts at $49 per month with 25,000 daily requests. Enterprise plans with custom limits are available for high-traffic use cases.
What data formats does the API support?
The API exclusively uses JSON for both requests and responses. All endpoints accept standard query parameters for GET requests and JSON request bodies for POST requests. Response encoding is UTF-8, which properly handles food names in all supported languages.
How accurate is the nutrition data provided by the API?
Every entry in the Nutrola database goes through a multi-layer verification process including government source validation, manufacturer data cross-referencing, AI-powered statistical checking, and human expert review. Our accuracy benchmark is 97.4% against laboratory analysis, compared to an industry average of 70-85% for crowdsourced databases. Each food entry includes a confidence_score field indicating our certainty level.
Can I use the API to build a commercial product?
Yes. The API is designed for commercial use. The free tier can be used for commercial products within its rate limits. Growth and Enterprise plans include commercial usage rights with no restrictions on the type of application. Review the terms of service at developer.nutrola.com for full details.
Does the API support foods from outside the United States?
Yes. The database covers branded products from 47 countries and generic foods from over 120 cuisines. Use the country parameter on search endpoints to prioritize results from a specific market. Barcode lookups automatically match the product to the correct regional formulation.
How do I handle foods that are not in the database?
If a barcode lookup returns a 404, you can fall back to a text search using the product name. If neither approach finds the food, you can submit it for addition through the developer portal. Foods submitted by API partners are prioritized for verification and typically added within 72 hours. Enterprise customers can request batch additions for large product catalogs.
Are there SDKs or client libraries available?
We provide official client libraries for Python (via pip: pip install nutrola), JavaScript/TypeScript (via npm: npm install @nutrola/api), and Swift (via Swift Package Manager). These libraries handle authentication, rate limiting, retries, and response parsing. Community-maintained libraries are available for Go, Ruby, and PHP.
Ready to Transform Your Nutrition Tracking?
Join thousands who have transformed their health journey with Nutrola!