Habit AI
Track health and nutrition through the Habit AI REST API.
Setup (100% Free)
Habit AI is a completely free service — no subscription, no credit card, no usage limits.
- 1. Create a free account at https://habitapp.ai (or download the free iOS app)
- Go to Settings → API Keys → Create Key (free, up to 5 keys)
- Store key in environment: INLINECODE0
All requests use:
- - Base URL: INLINECODE1
- Auth header: INLINECODE2
- Content-Type: INLINECODE3
Quick Reference
| Action | Method | Endpoint |
|---|
| Log a meal | POST | INLINECODE4 |
| Today's meals |
GET |
/meals?date=YYYY-MM-DD |
| Daily nutrition | GET |
/nutrition/daily?date=YYYY-MM-DD |
| Weekly nutrition | GET |
/nutrition/weekly?date=YYYY-MM-DD |
| Log water (ml) | POST |
/water |
| Log weight (kg) | POST |
/weight |
| Log steps | POST |
/steps |
| Log meditation | POST |
/meditation |
| Journal entry | POST |
/journal |
| AI eating coach | POST |
/coaches/eating |
| AI mindfulness coach | POST |
/coaches/mindfulness |
| AI meditation coach | POST |
/coaches/meditation |
| Get profile | GET |
/profile |
| Update profile | PUT |
/profile |
For full endpoint details (request/response schemas, all parameters), see references/api.md.
Logging Meals — The Right Way
⚠️ CRITICAL: Use the AI model to analyze food, then POST /meals with the EXACT structure below
Do NOT call /analyze/food-image or /analyze/meal-description — instead, use your own vision/language capabilities to analyze the food, then construct the exact JSON structure below and POST it to /meals.
Step 0: Check user profile for allergens/diet
Before analyzing, call GET /profile to check foodSensitivities and diet fields. Factor these into:
- - healthScore — lower the score if the meal contains ingredients the user is sensitive to
- healthScoreExplanation — mention the general nutritional pros/cons
- healthSensitivityExplanation — if the meal contains any of the user's allergens/sensitivities, explain which ingredients are problematic and why. Leave empty string if no sensitivities match.
Step 1: Analyze the food yourself
For photos: Look at the image and identify each ingredient, estimate portions, and calculate nutrition using USDA data.
For descriptions: Parse the meal description and calculate nutrition the same way.
Step 2: POST /meals with the EXACT structure
Every field matters. iOS reads from nutritionalSummary (nested object) — if it's missing, meals show as 0 calories.
CODEBLOCK0
Field Reference
| Field | Type | Required | Description |
|---|
| INLINECODE25 | string | Yes | Display name (e.g. "Chicken Caesar Salad"). Without this, the meal has no name in the app. |
| INLINECODE26 |
number |
Yes | Total calories (kcal). Must be > 0. |
|
protein | number | Yes | Total protein in grams |
|
carbs | number | Yes | Total carbohydrates in grams |
|
fat | number | Yes | Total fat in grams |
|
fiber | number | Yes | Total fiber in grams |
|
sodium | number | Yes | Total sodium in milligrams |
|
sugar | number | Yes | Total sugar in grams |
|
healthScore | integer | Yes | 1-10. How healthy is this meal overall? (1=very unhealthy, 10=very healthy) |
|
mealType | string | Yes | One of:
breakfast,
lunch,
dinner,
snack |
|
analysisConfidenceLevel | integer | Yes | 1-10. How confident are you in the nutrition estimates? (1=wild guess, 10=exact data from packaging). For photo analysis use 6-8, for descriptions use 5-7. |
|
healthScoreExplanation | string | Yes | 1-2 sentence explanation of the nutritional pros/cons (e.g. "Good protein from chicken but high sodium from the sausage and dressing.") |
|
healthSensitivityExplanation | string | Yes | If the meal contains any of the user's allergens/food sensitivities (from profile), explain which ingredients are problematic. Empty string
"" if no sensitivities match or user has none set. |
|
ingredients | array | Yes | Array of ingredient objects (see below) |
|
imageUrl | string | No | URL of the food photo. Get this from
POST /meals/upload-image first (see below). |
|
dateScanned | string | No | ISO 8601 timestamp. Defaults to now if omitted. |
|
serving | number | No | Serving multiplier (defaults to 1.0) |
Ingredient Object
Each ingredient in the ingredients array must have:
| Field | Type | Description |
|---|
| INLINECODE49 | string | Ingredient name (e.g. "grilled chicken breast") |
| INLINECODE50 |
number | Calories for this ingredient's portion (kcal) |
|
protein | number | Protein in grams |
|
carbs | number | Carbs in grams |
|
fat | number | Fat in grams |
|
sugar | number | Sugar in grams |
|
fiber | number | Fiber in grams |
|
sodium | number | Sodium in milligrams |
|
healthScore | integer | 1-10 health score for this specific ingredient |
|
measurementType | string |
Must be one of: grams,
ounces,
cups,
spoons,
servings. Use
servings for pieces/slices/bowls/items. Use
spoons for tablespoons/teaspoons. |
|
measurementValue | number | Amount in the specified unit |
Important Rules
- 1. All nutrition values must be numbers, not strings.
"calories": 520 not INLINECODE68 - Ingredient calories should sum to the total calories (approximately — within 5%)
mealName is mandatory — without it, the meal is invisible on iOShealthScore is 1-10 integer — use your judgment (fast food = 2-4, home-cooked balanced = 6-8, raw salad = 9-10)analysisConfidenceLevel is 1-10 integer — be honest about uncertainty- Sodium is in milligrams, everything else is in grams (except calories in kcal)
Uploading a meal photo (thumbnail)
If you have a food photo, upload it first to get a URL:
CODEBLOCK1
Returns: INLINECODE72
Then pass imageUrl in your POST /meals call. You can also attach to an existing meal:
CODEBLOCK2
Full flow with photo:
- 1.
POST /meals/upload-image with base64 photo → get INLINECODE75 - INLINECODE76 with nutrition data + INLINECODE77
Other Workflows
Check remaining calories
- 1. GET
/nutrition/daily for today's totals - GET
/profile for calorie goal - Subtract: INLINECODE80
Quick water log
CODEBLOCK3
Amount is in milliliters. 1 cup ≈ 237ml, 1 glass ≈ 250ml.
Notes
- - Dates default to today if omitted (uses user's timezone from profile)
- Water amount is in milliliters
- Weight is in kilograms (1 lb ≈ 0.4536 kg)
- Steps auto-calculate calories burned if profile has height/weight/gender
- Max 5 API keys per account
Habit AI
通过Habit AI REST API追踪健康与营养。
设置(100%免费)
Habit AI是完全免费的服务——无需订阅、无需信用卡、无使用限制。
- 1. 在 https://habitapp.ai 创建免费账户(或下载免费iOS应用)
- 前往 设置 → API密钥 → 创建密钥(免费,最多5个密钥)
- 将密钥存入环境变量:export HABITAIAPIKEY=hab_...
所有请求使用:
- - 基础URL:https://habitapp.ai/api/v1
- 认证头:Authorization: Bearer $HABITAIAPIKEY
- 内容类型:application/json
快速参考
GET | /meals?date=YYYY-MM-DD |
| 每日营养 | GET | /nutrition/daily?date=YYYY-MM-DD |
| 每周营养 | GET | /nutrition/weekly?date=YYYY-MM-DD |
| 记录饮水量(毫升) | POST | /water |
| 记录体重(公斤) | POST | /weight |
| 记录步数 | POST | /steps |
| 记录冥想 | POST | /meditation |
| 日记条目 | POST | /journal |
| AI饮食教练 | POST | /coaches/eating |
| AI正念教练 | POST | /coaches/mindfulness |
| AI冥想教练 | POST | /coaches/meditation |
| 获取个人资料 | GET | /profile |
| 更新个人资料 | PUT | /profile |
如需完整的端点详情(请求/响应模式、所有参数),请参阅 references/api.md。
记录餐食——正确方法
⚠️ 关键:使用AI模型分析食物,然后使用以下精确结构POST到/meals
不要调用 /analyze/food-image 或 /analyze/meal-description——而是使用你自己的视觉/语言能力分析食物,然后构建以下精确的JSON结构并POST到 /meals。
第0步:检查用户资料中的过敏原/饮食限制
在分析之前,调用 GET /profile 检查 foodSensitivities 和 diet 字段。将这些因素纳入考虑:
- - healthScore —— 如果餐食含有用户敏感的成分,降低分数
- healthScoreExplanation —— 提及总体营养优缺点
- healthSensitivityExplanation —— 如果餐食含有用户的任何过敏原/敏感成分,解释哪些成分有问题及原因。如果没有匹配的敏感成分,则留空字符串。
第1步:自行分析食物
对于照片:查看图片,识别每种成分,估算份量,并使用USDA数据计算营养。
对于描述:解析餐食描述,并以相同方式计算营养。
第2步:使用精确结构POST到/meals
每个字段都很重要。iOS从 nutritionalSummary(嵌套对象)读取数据——如果缺失,餐食将显示为0卡路里。
json
{
mealName: 烤鸡沙拉配牧场酱,
calories: 520,
protein: 42,
carbs: 18,
fat: 32,
fiber: 4,
sodium: 890,
sugar: 6,
healthScore: 7,
healthScoreExplanation: 烤鸡提供瘦蛋白,绿叶蔬菜提供纤维,但牧场酱增加了大量脂肪和钠。,
mealType: lunch,
analysisConfidenceLevel: 8,
ingredients: [
{
name: 烤鸡胸肉,
calories: 280,
protein: 35,
carbs: 0,
fat: 14,
sugar: 0,
fiber: 0,
sodium: 400,
healthScore: 8,
measurementType: grams,
measurementValue: 200
},
{
name: 混合沙拉绿叶菜,
calories: 20,
protein: 2,
carbs: 4,
fat: 0,
sugar: 1,
fiber: 2,
sodium: 30,
healthScore: 9,
measurementType: cups,
measurementValue: 2
},
{
name: 牧场酱,
calories: 220,
protein: 5,
carbs: 14,
fat: 18,
sugar: 5,
fiber: 2,
sodium: 460,
healthScore: 3,
measurementType: spoons,
measurementValue: 3
}
]
}
字段参考
| 字段 | 类型 | 必需 | 描述 |
|---|
| mealName | 字符串 | 是 | 显示名称(例如凯撒鸡肉沙拉)。没有此字段,餐食在应用中将没有名称。 |
| calories |
数字 |
是 | 总卡路里(千卡)。必须大于0。 |
| protein | 数字 | 是 | 总蛋白质(克) |
| carbs | 数字 | 是 | 总碳水化合物(克) |
| fat | 数字 | 是 | 总脂肪(克) |
| fiber | 数字 | 是 | 总纤维(克) |
| sodium | 数字 | 是 | 总钠(毫克) |
| sugar | 数字 | 是 | 总糖(克) |
| healthScore | 整数 | 是 | 1-10。这餐整体有多健康?(1=非常不健康,10=非常健康) |
| mealType | 字符串 | 是 | 以下之一:breakfast、lunch、dinner、snack |
| analysisConfidenceLevel | 整数 | 是 | 1-10。你对营养估算的自信程度?(1=随意猜测,10=来自包装的精确数据)。照片分析使用6-8,描述分析使用5-7。 |
| healthScoreExplanation | 字符串 | 是 | 1-2句解释营养优缺点(例如鸡肉提供优质蛋白质,但香肠和酱汁导致钠含量较高。) |
| healthSensitivityExplanation | 字符串 | 是 | 如果餐食含有用户的任何过敏原/食物敏感成分(来自个人资料),解释哪些成分有问题。如果没有匹配的敏感成分或用户未设置,则为空字符串。 |
| ingredients | 数组 | 是 | 成分对象数组(见下文) |
| imageUrl | 字符串 | 否 | 食物照片的URL。先通过 POST /meals/upload-image 获取(见下文)。 |
| dateScanned | 字符串 | 否 | ISO 8601时间戳。如果省略,默认为当前时间。 |
| serving | 数字 | 否 | 份量倍数(默认为1.0) |
成分对象
ingredients 数组中的每个成分必须包含:
| 字段 | 类型 | 描述 |
|---|
| name | 字符串 | 成分名称(例如烤鸡胸肉) |
| calories |
数字 | 该成分份量的卡路里(千卡) |
| protein | 数字 | 蛋白质(克) |
| carbs | 数字 | 碳水化合物(克) |
| fat | 数字 | 脂肪(克) |
| sugar | 数字 | 糖(克) |
| fiber | 数字 | 纤维(克) |
| sodium | 数字 | 钠(毫克) |
| healthScore | 整数 | 该特定成分的1-10健康评分 |
| measurementType | 字符串 |
必须是以下之一: grams、ounces、cups、spoons、servings。对于块/片/碗/件使用 servings。对于汤匙/茶匙使用 spoons。 |
| measurementValue | 数字 | 指定单位的数量 |
重要规则
- 1. 所有营养值必须是数字,而非字符串。 calories: 520 而非 calories: 520
- 成分卡路里之和应约等于总卡路里(误差在5%以内)
- mealName 是必需的——没有它,餐食在iOS上不可见