开发者免费营养API:如何使用Nutrola的食品数据构建应用
本开发者指南介绍如何使用Nutrola的免费营养API构建营养意识应用程序。涵盖端点、身份验证、Python、JavaScript和cURL中的代码示例、速率限制以及与Nutritionix、Edamam和USDA API的比较。
过去,构建一个具备营养意识的应用程序需要从头开始组建自己的食品数据库,购买昂贵的数据集,或者从不可靠的来源抓取数据。而如今,营养API提供了结构化的程序化访问,能够获取全面的食品数据库,包括宏观营养素、微观营养素和份量数据,且以干净的JSON格式传递。本文将引导开发者了解营养API的现状,重点介绍如何开始使用Nutrola的免费套餐以及与其他选择的比较。
无论您是在构建一款餐食规划应用、健身追踪器、研究工具、食谱分析器,还是一个能够回答营养问题的AI助手,本文都将为您提供技术细节,帮助您选择API并在几分钟内开始发起请求。
营养API概述
在深入实施之前,以下是2026年可供开发者使用的主要营养API的比较。
| API | 免费套餐 | 速率限制(免费) | 数据库中的食品数量 | 条形码扫描 | 食品识别(AI) | 付费定价 |
|---|---|---|---|---|---|---|
| Nutrola API | 是 | 500请求/天 | 900,000+ | 是 | 是(附加功能) | 从$29/月起 |
| USDA FoodData Central | 是(完全免费) | 每个密钥1,000/小时 | 370,000+ | 否 | 否 | 免费 |
| Nutritionix API | 是(有限) | 50请求/天 | 1,000,000+ | 是 | 否 | 从$299/月起 |
| Edamam API | 是 | 100请求/天 | 900,000+ | 否 | 否 | 从$19/月起 |
| FatSecret Platform API | 是 | 5,000请求/天 | 500,000+ | 是 | 否 | 免费(需注明出处) |
| Open Food Facts API | 是(完全免费) | 合理使用 | 3,000,000+ | 是 | 否 | 免费 |
| Spoonacular | 是 | 150请求/天 | 500,000+ | 否 | 否 | 从$29/月起 |
开始使用Nutrola API
第一步:创建开发者账户
访问Nutrola开发者门户网站 developers.nutrola.com 创建一个免费账户。完成邮箱验证后,您将在仪表板上收到一个API密钥。免费套餐包括每天500个请求、访问完整的食品数据库和基于文本的食品搜索。AI食品识别端点在付费套餐中提供。
第二步:身份验证
所有API请求都需要在请求头中包含您的API密钥。密钥通过X-Api-Key头传递。
X-Api-Key: your_api_key_here
API仅使用HTTPS。所有对HTTP端点的请求将收到301重定向到HTTPS。请勿将API密钥嵌入客户端代码;始终通过后端服务器代理请求。
第三步:基础URL
所有端点均通过以下地址提供:
https://api.nutrola.com/v1/
响应采用JSON格式,使用UTF-8编码。API遵循RESTful约定,使用标准HTTP状态码。
核心端点
搜索食品
通过文本查询搜索食品数据库。返回匹配的食品及其营养数据。
端点: GET /v1/foods/search
参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| query | string | 是 | 搜索词(例如,“烤鸡胸肉”) |
| limit | integer | 否 | 每页结果数(默认:10,最大:50) |
| offset | integer | 否 | 分页偏移(默认:0) |
| type | string | 否 | 按类型过滤:“common”、“branded”、“restaurant” |
| language | string | 否 | 语言代码(默认:“en”)。支持:en、es、de、fr、pt、ja、ko、zh |
示例请求(cURL):
curl -X GET "https://api.nutrola.com/v1/foods/search?query=grilled+chicken+breast&limit=5" \
-H "X-Api-Key: your_api_key_here"
示例请求(Python):
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.nutrola.com/v1"
response = requests.get(
f"{BASE_URL}/foods/search",
headers={"X-Api-Key": API_KEY},
params={
"query": "grilled chicken breast",
"limit": 5
}
)
data = response.json()
for food in data["foods"]:
print(f"{food['name']}: {food['calories']} kcal per {food['serving_size']}{food['serving_unit']}")
示例请求(JavaScript / Node.js):
const API_KEY = "your_api_key_here";
const BASE_URL = "https://api.nutrola.com/v1";
async function searchFoods(query) {
const url = new URL(`${BASE_URL}/foods/search`);
url.searchParams.append("query", query);
url.searchParams.append("limit", "5");
const response = await fetch(url, {
headers: { "X-Api-Key": API_KEY }
});
const data = await response.json();
return data.foods;
}
searchFoods("grilled chicken breast").then(foods => {
foods.forEach(food => {
console.log(`${food.name}: ${food.calories} kcal per ${food.serving_size}${food.serving_unit}`);
});
});
示例响应:
{
"foods": [
{
"id": "nf_001234",
"name": "Chicken Breast, Grilled, Skinless",
"type": "common",
"calories": 165,
"protein_g": 31.0,
"carbohydrates_g": 0.0,
"fat_g": 3.6,
"fiber_g": 0.0,
"sugar_g": 0.0,
"sodium_mg": 74,
"serving_size": 100,
"serving_unit": "g",
"serving_description": "100 grams",
"alt_servings": [
{
"description": "1 medium breast (196g)",
"multiplier": 1.96
},
{
"description": "1 oz (28g)",
"multiplier": 0.28
}
],
"source": "USDA SR Legacy",
"updated": "2026-01-15"
}
],
"total_results": 47,
"offset": 0,
"limit": 5
}
根据ID获取食品
通过Nutrola ID检索特定食品项的详细营养数据。
端点: GET /v1/foods/{food_id}
示例(cURL):
curl -X GET "https://api.nutrola.com/v1/foods/nf_001234" \
-H "X-Api-Key: your_api_key_here"
响应包括 完整的宏观和微观营养素信息(30+种营养素)、所有可用的份量、成分列表(针对品牌和餐厅项目)、过敏原标记、饮食标签(素食、无麸质、清真、犹太洁食)以及来源归属。
根据条形码获取食品
通过UPC或EAN条形码查找包装食品。
端点: GET /v1/foods/barcode/{code}
参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| code | string | 是 | UPC(12位)或EAN(13位)条形码 |
示例(Python):
response = requests.get(
f"{BASE_URL}/foods/barcode/041331092609",
headers={"X-Api-Key": API_KEY}
)
food = response.json()
print(f"{food['name']}: {food['calories']} kcal per {food['serving_description']}")
分析自然语言输入
解析自然语言的食品描述并返回结构化的营养数据。此端点处理数量、单位、准备方法和单个字符串中的多个项目。
端点: POST /v1/foods/analyze
请求体:
{
"query": "2 scrambled eggs with a slice of whole wheat toast and half an avocado",
"language": "en"
}
示例(Python):
response = requests.post(
f"{BASE_URL}/foods/analyze",
headers={
"X-Api-Key": API_KEY,
"Content-Type": "application/json"
},
json={
"query": "2 scrambled eggs with a slice of whole wheat toast and half an avocado"
}
)
result = response.json()
for item in result["items"]:
print(f"{item['quantity']} {item['unit']} {item['name']}: {item['calories']} kcal")
print(f"Total: {result['total']['calories']} kcal")
示例响应:
{
"items": [
{
"name": "Scrambled Eggs",
"quantity": 2,
"unit": "large",
"calories": 182,
"protein_g": 12.2,
"carbohydrates_g": 2.4,
"fat_g": 13.6,
"food_id": "nf_002891"
},
{
"name": "Whole Wheat Toast",
"quantity": 1,
"unit": "slice",
"calories": 81,
"protein_g": 3.9,
"carbohydrates_g": 13.8,
"fat_g": 1.1,
"food_id": "nf_003401"
},
{
"name": "Avocado",
"quantity": 0.5,
"unit": "medium",
"calories": 120,
"protein_g": 1.5,
"carbohydrates_g": 6.4,
"fat_g": 11.0,
"food_id": "nf_000892"
}
],
"total": {
"calories": 383,
"protein_g": 17.6,
"carbohydrates_g": 22.6,
"fat_g": 25.7
}
}
AI食品识别(付费套餐)
提交食品照片以进行AI驱动的识别和营养分析。
端点: POST /v1/foods/recognize
请求: 使用图像文件的多部分表单数据,或使用包含base64编码图像的JSON体。
示例(Python):
with open("meal_photo.jpg", "rb") as f:
response = requests.post(
f"{BASE_URL}/foods/recognize",
headers={"X-Api-Key": API_KEY},
files={"image": ("meal.jpg", f, "image/jpeg")}
)
result = response.json()
for item in result["detected_items"]:
print(f"{item['name']} ({item['confidence']:.1%}): {item['calories']} kcal")
响应包括 检测到的食品项及其置信度分数、边界框坐标、估计的份量大小、每项的营养分解以及总餐食的营养摘要。
速率限制和错误处理
各套餐的速率限制
| 套餐 | 每日请求 | 每秒请求 | AI识别 | 价格 |
|---|---|---|---|---|
| 免费 | 500 | 5 | 不包括 | $0 |
| 初学者 | 5,000 | 10 | 100/天 | $29/月 |
| 专业 | 50,000 | 25 | 1,000/天 | $99/月 |
| 企业 | 自定义 | 自定义 | 自定义 | 联系销售 |
速率限制头
每个响应都包含速率限制头:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1710374400
错误响应
API使用标准HTTP状态码和描述性错误体。
{
"error": {
"code": "rate_limit_exceeded",
"message": "每日请求限制500已超出。将在00:00 UTC重置。",
"status": 429
}
}
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 错误请求(无效参数) |
| 401 | 未授权(无效或缺失API密钥) |
| 404 | 食品未找到 |
| 429 | 超过速率限制 |
| 500 | 服务器内部错误 |
对于429和500响应,实施指数退避策略。简单的策略是第一次失败后等待1秒,第二次等待2秒,第三次等待4秒,直到最大等待60秒。
用例和实施模式
餐食规划应用
构建一个餐食规划器,通过搜索食品、计算营养总量并迭代,直到餐食计划满足用户的目标。
def find_foods_for_target(target_protein, target_calories):
"""在卡路里预算内寻找富含蛋白质的食品。"""
response = requests.get(
f"{BASE_URL}/foods/search",
headers={"X-Api-Key": API_KEY},
params={
"query": "high protein",
"limit": 20,
"type": "common"
}
)
foods = response.json()["foods"]
# 按蛋白质与卡路里比率过滤
efficient_foods = [
f for f in foods
if f["protein_g"] / max(f["calories"], 1) > 0.15
]
return sorted(efficient_foods, key=lambda f: f["protein_g"], reverse=True)
健身应用集成
结合活动数据向用户展示卡路里平衡。使用自然语言端点进行快速记录。
async function logMealFromText(description) {
const response = await fetch(`${BASE_URL}/foods/analyze`, {
method: "POST",
headers: {
"X-Api-Key": API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({ query: description })
});
const data = await response.json();
// 存储到您的数据库
await db.meals.insert({
user_id: currentUser.id,
items: data.items,
total_calories: data.total.calories,
total_protein: data.total.protein_g,
timestamp: new Date()
});
return data;
}
食谱营养计算器
通过查找每种成分并汇总数值来计算食谱的营养成分。
def analyze_recipe(ingredients):
"""
ingredients: 字符串列表,如["200g鸡胸肉", "1杯糙米", "2汤匙橄榄油"]
"""
recipe_nutrition = {"calories": 0, "protein_g": 0, "carbohydrates_g": 0, "fat_g": 0}
for ingredient in ingredients:
response = requests.post(
f"{BASE_URL}/foods/analyze",
headers={
"X-Api-Key": API_KEY,
"Content-Type": "application/json"
},
json={"query": ingredient}
)
data = response.json()
for item in data["items"]:
recipe_nutrition["calories"] += item["calories"]
recipe_nutrition["protein_g"] += item["protein_g"]
recipe_nutrition["carbohydrates_g"] += item["carbohydrates_g"]
recipe_nutrition["fat_g"] += item["fat_g"]
return recipe_nutrition
# 示例用法
recipe = analyze_recipe([
"200g鸡胸肉",
"1杯煮熟的糙米",
"2汤匙橄榄油",
"1杯蒸西兰花"
])
print(f"食谱总计:{recipe['calories']} kcal, {recipe['protein_g']}g蛋白质")
研究与数据分析
对于学术研究,使用API构建研究人群的营养档案或验证饮食评估工具。
import pandas as pd
def build_nutrition_profile(food_log_df):
"""
food_log_df: DataFrame,包含['food_description', 'date']列
返回每个条目的完整营养分解的DataFrame。
"""
results = []
for _, row in food_log_df.iterrows():
response = requests.post(
f"{BASE_URL}/foods/analyze",
headers={
"X-Api-Key": API_KEY,
"Content-Type": "application/json"
},
json={"query": row["food_description"]}
)
data = response.json()
results.append({
"date": row["date"],
"description": row["food_description"],
"calories": data["total"]["calories"],
"protein_g": data["total"]["protein_g"],
"carbs_g": data["total"]["carbohydrates_g"],
"fat_g": data["total"]["fat_g"]
})
return pd.DataFrame(results)
与替代API的比较
USDA FoodData Central API
USDA API完全免费且没有付费套餐,是学术和政府项目的默认选择。它涵盖约370,000种食品,来自基础、SR Legacy、调查(FNDDS)和品牌数据库。优点是被认为是美国食品成分数据的金标准,其他数据库都以其为参考。缺点是没有自然语言解析(必须将食品名称与其特定数据库键匹配),没有条形码查找,没有AI识别,品牌食品数据可能不一致,因为它依赖于制造商的提交。API文档功能齐全,但相较于现代标准不够友好。
适合: 学术研究、政府项目、需要权威参考数据且具备开发资源以处理匹配复杂性的应用。
Nutritionix API
Nutritionix拥有最大的食品数据库之一,餐厅和品牌食品的覆盖率强。其自然语言端点成熟,能够很好地处理复杂查询。然而,免费套餐每天仅限50个请求,付费计划起价为$299/月,这使得许多独立开发者和小型初创企业难以承受。API文档完善,支持文本和条形码查找。
适合: 资金充足的应用,需要广泛的餐厅食品数据且能够承担定价。
Edamam API
Edamam提供营养分析、食谱分析和食品数据库API。免费套餐每天提供100个请求,适合原型开发。Edamam的优势在于其食谱分析能力,能够解析完整食谱的成分列表并返回每份的营养数据。数据库涵盖约900,000种食品。缺点包括偶尔出现的份量数据不一致和相较于更新API的开发者体验不够直观。
适合: 以食谱为中心的应用、需要食谱级分析的餐食规划工具。
FatSecret Platform API
FatSecret提供了慷慨的免费套餐,每天5,000个请求,吸引了许多初创项目。缺点是您必须在应用中显示FatSecret的品牌和归属。数据库涵盖约500,000种食品,国际覆盖率不错。API支持OAuth 1.0身份验证,这种方式较旧且实现起来比API密钥或OAuth 2.0复杂。
适合: 预算有限的项目,能够满足归属要求和OAuth 1.0。
Open Food Facts API
Open Food Facts是一个社区驱动的开源食品数据库,拥有超过300万种产品,主要是带有条形码的数据包装食品。它完全免费且开放(开放数据库许可证)。API对于条形码查找非常简单,但对营养搜索查询的结构化程度较低。由于数据是众包的,数据质量各异,但社区审核过程能捕捉到许多错误。
适合: 包装食品条形码扫描、与开源原则一致的项目、国际包装食品覆盖。
API比较总结
| 特性 | Nutrola | USDA | Nutritionix | Edamam | FatSecret | Open Food Facts |
|---|---|---|---|---|---|---|
| 免费套餐每日限制 | 500 | 1,000/小时 | 50 | 100 | 5,000 | 无限 |
| 自然语言解析 | 是 | 否 | 是 | 是 | 否 | 否 |
| AI食品识别 | 是(付费) | 否 | 否 | 否 | 否 | 否 |
| 条形码查找 | 是 | 否 | 是 | 否 | 是 | 是 |
| 多语言支持 | 8种语言 | 英语 | 英语 | 英语 | 16种语言 | 40+种语言 |
| 食谱分析 | 通过NLP | 否 | 是 | 是 | 否 | 否 |
| 微量营养素深度 | 30+种营养素 | 60+种营养素 | 20+种营养素 | 25+种营养素 | 15+种营养素 | 变化 |
| 身份验证 | API密钥 | API密钥 | API密钥 | 应用ID + 密钥 | OAuth 1.0 | 无(可选) |
构建营养应用的最佳实践
积极缓存
常见食品的营养数据变化不频繁。将食品搜索结果和营养查找结果在您的后端缓存24到72小时,以减少API调用并提高响应速度。
优雅处理缺失数据
并非每个食品条目都有完整的微量营养素数据。设计您的用户界面,以指示数据不可用,而不是显示零,这可能会让用户误解为“该食品含有零铁”。
在API调用前验证用户输入
在将数据发送到API之前,修剪空格、标准化单位并检查食品名称的拼写。格式良好的查询比拼写错误的查询能产生更好的结果。
尽可能使用自然语言端点
与其构建自己的食品名称解析器,不如使用/foods/analyze端点。它比大多数自定义实现更好地处理数量(“2杯”)、准备方法(“烤”)和复合描述(“全麦吐司加黄油”)。
尊重速率限制
实施适当的退避逻辑。尽可能批量操作。对于高流量操作,使用Webhook或队列,而不是同步API调用。
归属数据源
良好的做法(有时根据API的要求也是法律要求)是归属数据源。在您的应用中显示“营养数据由Nutrola提供”或您使用的任何API的等效内容。
常见问题解答
Nutrola API真的是免费的吗?
是的。免费套餐提供每天500个API请求,无需信用卡。这对于原型开发、小型应用和个人项目来说足够了。免费套餐包括文本搜索、按ID查找食品、条形码扫描和自然语言分析。图像的AI食品识别在从$29/月起的付费套餐中提供。
API返回的数据格式是什么?
所有响应均为JSON格式,使用UTF-8编码。营养值使用标准单位:能量以千卡(kcal)表示,宏观营养素和纤维以克(g)表示,钠和大多数矿物质以毫克(mg)表示,维生素则以微克(μg)表示(适用时)。
我可以在商业应用中使用Nutrola API吗?
可以。免费和付费套餐均允许商业使用。免费套餐要求在您的应用中注明Nutrola的归属。付费套餐包括不需要归属的白标选项。
食品数据库更新的频率如何?
Nutrola食品数据库持续更新品牌和餐厅食品,USDA参考数据在USDA发布后的30天内同步。每月进行一次主要数据库刷新,而单个食品条目可能会根据制造商的更改、用户报告的修正和新产品的推出而每天更新。
API支持国际食品吗?
是的。数据库涵盖来自50多个国家的食品,支持8种语言(英语、西班牙语、德语、法语、葡萄牙语、日语、韩语和中文)。国际食品覆盖是Nutrola的核心优先事项,数据库包括区域菜肴、本地品牌产品和通常缺失的特定于菜系的准备方式。
我可以将API用于移动应用吗?
可以,但请勿直接在移动客户端代码中嵌入您的API密钥,因为它可能会从应用程序二进制文件中提取。相反,设置一个轻量级的后端服务器,代理请求到Nutrola API并处理身份验证。这也为您提供了缓存和请求管理的层。
是否有Webhook或流选项?
目前,API采用请求-响应模型。2026年将推出异步食品识别结果的Webhook支持(用于大批量处理)。对于今天的批量操作,请使用/v1/foods/analyze/batch端点,该端点一次接受多达20个项目的请求。
结论
营养API使开发者能够构建食品意识应用程序,而无需承担维护专有食品数据库的巨大开销。Nutrola的API提供了慷慨的免费套餐、全面的国际美食覆盖、自然语言理解和可选的AI食品识别,使其成为从周末原型到生产应用的强大选择。
您项目的最佳API取决于您的具体需求:USDA用于权威参考数据,Nutritionix用于深入的餐厅覆盖,Open Food Facts用于开源条形码数据,或Nutrola用于功能、准确性和开发者体验的平衡。在许多情况下,结合多个API可以为您提供最佳覆盖。首先从免费套餐开始,根据您的用例进行验证,然后再进行扩展。