Units of Measurement & User Preferred Measurements
What You’ll Build
You’ll implement a measurement-aware intake flow that adapts units to each user’s preferences at both dish and ingredient level. Your app will retrieve the available units (weight and cooking measures, plus portion sizes), determine which ones apply to specific dishes/ingredients (respecting solid vs liquid), and display them in the user’s preferred system. When users select a unit (e.g., cups, teaspoons, slices) or a portion size (e.g., 1/2, 1/4), the app converts to grams for submission to the API and for consistent recalculation of ingredients and nutrition.
This addresses the complexity of regional systems (metric vs imperial) and culinary language (cooking measures) while maintaining precision, ensuring a smooth UX for end users and predictable data for developers.
Prerequisites
- Plan: Monitor and above (see more info about LogMeal Plans)
- User type: 🔴 APIUser (see more info about User Types)
- Client library for HTTP (e.g., Python
requests
, Nodeaxios
, JavaOkHttp
). - 1–2 sample food images (JPEG/PNG) or a saved intake to test measures at dish and ingredient level.
Sequence Diagrams
sequenceDiagram participant User participant App participant LogMeal API User->>App: Capture/choose meal photo or open existing intake App->>LogMeal API: POST /v2/image/segmentation/complete <br> (Authorization: 🔴 **APIUser** token, image) LogMeal API-->>App: 200 OK (imageId, segmentation results) App-->>User: Show top dish candidates per detected item User->>App: Confirm/adjust dish per item App->>LogMeal API: POST /v2/image/confirm/dish (imageId, confirmed items) LogMeal API-->>App: 200 OK (confirmed items) Note over App,LogMeal API: Load available measurements App->>LogMeal API: GET /v2/dataset/weightMeasures/dishes LogMeal API-->>App: 200 OK (dish-level weight + cooking measures) App->>LogMeal API: GET /v2/dataset/weightMeasures/ingredients LogMeal API-->>App: 200 OK (ingredient-level weight + cooking measures) Note over App,LogMeal API: Resolve applicable cooking measures per item App->>LogMeal API: GET /v2/dataset/dishes?cooking_measures LogMeal API-->>App: 200 OK (dish.cooking_measures IDs) App->>LogMeal API: GET /v2/dataset/ingredients?cooking_measures LogMeal API-->>App: 200 OK (ingredient.cooking_measures IDs) App-->>User: Display measures by item (solid/liquid aware) in preferred system User->>App: Select units/amounts (e.g., 1 cup, 2 slices, portions like 1/2 apply to dishes only) App-->>App: Convert to grams using grams_conversion opt Quantity confirmation (optional) App->>LogMeal API: POST /v2/nutrition/confirm/quantity (imageId, per-item grams + optional measures) LogMeal API-->>App: 200 OK (updated quantities) end App->>LogMeal API: GET /v2/intake/{imageId} LogMeal API-->>App: 200 OK (dishes, ingredients, nutrition with measures and weights) App-->>User: Display standardized measures + recalculated quantities
Implementation Guide
Implementation Examples
Understanding the measurement systems
- 1) Basic Weight Measurements: precise, global; metric (e.g., grams, milliliters) and imperial (e.g., ounce, pound, teaspoon). Valid for dishes and ingredients; each unit carries
state
(solid/liquid) andtype
(metric/imperial).- 2) Cooking Measurements: user-friendly, less precise; split into ingredient-specific (e.g., teaspoon, drop, slice) and dish-specific (e.g., glass, cup, fillet). Applicability is item-dependent—e.g., “slice” applies to cheese but not to water.
- 3) Portion Size: broad, dish-level amounts (e.g., 1/2, 1/4) that apply to dishes (high level), not to ingredients (low level).
Dish vs Ingredient scope
- High level (dishes/food items): e.g., cheesecake, pizza, sushi.
- Low level (ingredients): e.g., cheese, beef, pepperoni, salmon.
Cooking measures availability and solid vs liquid constraints differ per item and are discoverable via dataset endpoints.
Retrieving available measurements
- Dish level: GET /dataset/weightMeasures/dishes → returns
weight
andcooking_measures
for dishes; each weight unit includesstate
(solid/liquid) andtype
(metric/imperial). - Ingredient level: GET /dataset/weightMeasures/ingredients → returns
weight
andcooking_measures
for ingredients; each weight unit includesstate
andtype
. Also note that GET /dataset/ingredients returns astate
attribute (solid/liquid) for each ingredient, which you should use to filter applicable measurements.
Linking cooking measures to specific items
- Dish level: GET /dataset/dishes with
?cooking_measures
to receivecooking_measures
IDs for each dish; match them to IDs from dish-levelweightMeasures
. - Ingredient level: GET /dataset/ingredients with
?cooking_measures
to receivecooking_measures
IDs for each ingredient; match them to IDs from ingredient-levelweightMeasures
. - Item state (solid/liquid) is also exposed under each dish’s
measure
attribute when you retrieve intake details (see below).
Retrieving intake measures/weights
- Ingredients per intake: POST /nutrition/recipe/ingredients → returns
recipe_per_item
; each dish containsmeasure
(dish-level measures & weight). Insiderecipe
, each ingredient includes its specific measures/weights. - Full intake details: GET /intake/{imageId} → returns dishes, ingredients, nutrition, and detailed measures/weights for each entity.
User preferred measurements
- Set per dish and ingredient level using POST /profile/modifyUserProfileInfo. Your UI should default to these preferences, but always convert to grams before submission.
Units conversion & quantity confirmation
- Grams are the common denominator: every weight/cooking/portion unit provides a
grams_conversion
. - Convert user-entered amounts to grams client-side before calling write endpoints.
- Example: 2 ounces × the unit’s
grams_conversion
(28.34375) → 56.69 g (2 decimals is sufficient).
Related Code Examples (Recipes)
User Interaction Recommendations
- Let users toggle Metric / Imperial / Cooking per item, honoring global preferences from the profile.
- Show only applicable cooking measures for each item (respecting solid/liquid).
- Prefer grams as an internal canonical unit; display chosen units in the UI.
- Surface
grams_conversion
inline when users type amounts for transparency. - For portions (dish-level only), offer 1/4, 1/2, 3/4, 1 with quick actions and allow custom entry.
Related Endpoints
- GET /dataset/weightMeasures/dishes
- GET /dataset/weightMeasures/ingredients
- GET /dataset/dishes
- GET /dataset/ingredients
- POST /nutrition/recipe/ingredients
- GET /intake/{imageId}
- POST /profile/modifyUserProfileInfo
Common Pitfalls & Tips
- Don’t show cooking measures that are inapplicable to a given item (e.g., “slice” for liquids). Always filter by item and
state
. - Keep grams as the only write-time unit; convert from the user’s visible unit using
grams_conversion
. - Respect user preferred systems at both dish and ingredient levels; provide easy overrides per item.
- Localize labels and abbreviations (e.g., “oz”, “cup”) according to the selected system and user profile.
- When reading an intake, inspect
recipe_per_item
→measure
and ingredientrecipe
blocks for accurate display.
Name collisions across contexts (important)
Some labels (e.g., “cup”) can exist in multiple measurement systems or semantic levels with different IDs and grams_conversion
. For example:
- “cups” as an imperial liquid measure ≈ 240 g,
- “cups” as dish cooking measures with id=2 (≈240 g) used by dishes like “tea” (id 1308) or “hot chocolate” (id 2642),
- “cups” again as dish cooking measures with id=14 (≈170 g) for dishes like “irish coffee” (id 2653) or “coffee” (id 1291).
Always match by ID, not just by name, and use the provided grams_conversion
.
Optional Enhancements
- Add portion presets (1/4, 1/2, 3/4, 1) next to cooking measures for dishes.
- Provide unit search and recent favorites for commonly used measures.
- Offer a nutrition preview that updates live as the unit or amount changes.
- Educate users with lightweight tooltips on metric vs imperial differences.
Next Steps
- Chain with quantity confirmation and nutrition flows once units are set.
- Extend editing with Easy Ingredients Modulation.
- Review Plans & Limits and quotas before going to production.
Updated about 11 hours ago