Manual or Assigned Intakes

Create intakes without image-based food recognition. Submit regular dishes, ingredients, favorites, custom recipes and barcode products in one typed request, individually or in bulk, with optional display-only images.

Plan & Token Requirements

Feature available in the following LogMeal Plans:

Analyse
Monitor
Recommend
Custom

Accessible by the following User Types:

šŸ”“ APIUser | šŸ”µ APIUserManager

What It Does

Manual Intakes create a food intake without running image-based food recognition or segmentation.

The current endpoints support two request contracts:

  • Legacy manual input — the existing id / ingredients format remains supported for backwards compatibility.
  • Unified mixed input — every top-level item includes a type, allowing one intake to combine regular dishes, ingredient-only items, favorites, custom recipes, and previously resolved barcode products.

Use the unified contract for new food-picker integrations because the type and id pair explicitly identifies the resource namespace and allows heterogeneous foods to be submitted in the same intake.

A manual intake can also have an optional display-only image. This image is stored for history/UI presentation and never triggers food recognition, segmentation, barcode recognition, or nutritional recalculation.

manual intake food upload food diary
history and reporting intakes diary

Unified Mixed Input

The unified contract supports these top-level type values:

TypeIdentifier / contentsPurpose
dishLogMeal GeneralClass idRegular LogMeal dish
ingredientNested ingredients array, no top-level idIngredient-only food item
favoriteFavorite favorite_image_id as idReuse the target APIUser's saved favorite
custom_recipeCustom-recipe GeneralClass idReuse a recipe from the target APIUser's APICompany
barcode_food_itemBarcodeClass GeneralClass idUse a previously resolved barcode product as a complete food item

Nested recipe ingredients use either:

  • ingredient with ingredientId or ingredientName;
  • barcode_ingredient with barcodeClassId.

barcode_ingredient is a nested ingredient type, not a top-level food item.

Example mixed request:

{
  "intake_name": "Friday lunch",
  "dishes": [
    {
      "type": "dish",
      "id": 123,
      "quantity": 250
    },
    {
      "type": "ingredient",
      "name": "Homemade salad",
      "ingredients": [
        {
          "type": "ingredient",
          "ingredientId": 140,
          "ingredientAmount": 120
        },
        {
          "type": "barcode_ingredient",
          "barcodeClassId": 9502,
          "ingredientAmount": 30
        }
      ]
    },
    {
      "type": "favorite",
      "id": 701
    },
    {
      "type": "custom_recipe",
      "id": 88,
      "quantity": 180
    },
    {
      "type": "barcode_food_item",
      "id": 9501,
      "quantity": 100
    }
  ]
}

Do not mix legacy and unified items inside the same dishes array. If one item contains type, every item in that intake must use the unified contract. In a bulk request, different intakes entries may independently use legacy or unified input.

Use Unified Food Search to build one picker that returns normalized type + id references. If a barcode product has not been resolved yet, first call POST /barcode_scan/{barcode_id}; use its returned dish_id as the barcode class reference.

Related use case: Build a Unified Food Picker and Submit a Mixed Manual Intake

Creating Custom Dishes From Scratch

An APIUser or APIUserManager can also create a one-off food item from scratch without relying on a pre-existing catalog dish ID.

To execute this workflow, follow these 3 steps:

1. Define the Ingredient List
Retrieve valid ingredient IDs through GET /dataset/ingredients, then determine the ingredients and quantities. You may preview the resulting nutrition by calling POST /nutrition/recipe/compute_nutrients.

2. Create the Intake
Call POST /v2/intake/manualInput/{userId}. In the legacy contract, omit the dish id and provide a non-empty ingredients list containing valid ingredientId values. Add an optional non-empty dishes[].name to label that individual ingredient-only item. The independent root-level intake_name labels the complete intake.

3. Modify the Whole-Intake Name
If the user wants to rename the complete intake after it has been created, use POST /intake/{imageId}/modify_name. This edits intake_name; it is not an item-level rename mechanism.

For ingredient-only food items, catalog identifiers such as id and dish_id remain null. When dishes[].name is supplied, the submitted label is returned in the corresponding foodName and recipe_per_item[].name positions. When it is omitted, both name values remain null. Ingredients, serving size, measures, ingredient-derived food groups, nutritional information, and Nutri-Score are returned normally in either case.

Related use case: Create a Custom Dish from Scratch with a Manual Intake

Display-Only Images

You can attach an image either when creating the manual intake or after creation:

  • During single-user creation, send multipart/form-data to POST /v2/intake/manualInput/\{userId\} with the JSON payload serialized in data and the optional file in image.
  • During bulk assignment, the same multipart structure can attach one uploaded file independently to every created intake. Each resulting intake receives its own display-image record.
  • After creation, call POST /intake/{image_id}/display_image to attach or replace the display image.
  • Call DELETE /intake/{image_id}/display_image to remove the explicitly attached display image.

The maximum display-image upload size is 1 MB. Display-image operations do not change foods, recipes, quantities, nutrition, timestamp, or occasion.


When to Use It / Outcomes

  • Users do not have a photo or prefer manual entry.
  • A food picker must combine dishes, individual ingredients, favorites, custom recipes, and barcode products.
  • Professionals need to add the same or different meals for managed users, individually or in bulk.
  • You need a one-off ingredient-based food without creating a reusable catalog dish.
  • A manually entered meal should have a picture in history without running image recognition.
  • Output: the created intake or, for bulk assignment, one creation result per target APIUser.

Feature-Specific Details

  • Use type + id together in the unified contract; numeric IDs can belong to different food namespaces.
  • Favorites and custom recipes are resolved in the target APIUser's context. In bulk assignment, they are not resolved against the authenticated manager's own context.
  • A favorite is expanded from its saved state and may contain several food items, so it does not accept one aggregate quantity or an ingredients override.
  • For a regular dish, explicit ingredients replace the catalog recipe before modifier levels and top-level quantity scaling are applied.
  • levels modify salt, sugar, and oil before the resulting recipe is scaled to the requested top-level quantity.
  • A barcode must be resolved before it is used. barcode_food_item.id and nested barcode_ingredient.barcodeClassId both reference the BarcodeClass GeneralClass ID returned as dish_id by the barcode-resolution endpoint.
  • The stored recipe of a barcode ingredient is not recursively expanded into more nested ingredients.
  • For single-user creation, timestamp is optional and defaults to the target APIUser's current localized time.
  • For bulk assignment, every intake requires a timestamp in %Y/%m/%d, %H:%M:%S format.
  • Bulk entries may optionally provide either occasion or occasion_id, but never both. An explicit occasion overrides timestamp-based occasion inference.
  • Use the root-level intake_name as an optional label for the complete intake.

Related Endpoints

Create manual intakes

Select or resolve foods

Manage the created intake


Typical Workflow

  1. Discover the unified contract with GET /v2/food/types.
  2. Search selectable foods with GET /food/search and preserve both type and id from every selected result.
  3. Resolve new barcodes when needed through POST /barcode_scan/{barcode_id}.
  4. Build one typed dishes array. Use barcode_ingredient only inside another item's ingredients array.
  5. Submit one intake through POST /intake/manualInput/{userId}, or submit multiple managed-user intakes through POST /intake/manualInput/bulkAssign.
  6. Optionally attach a display image during creation with multipart form data, or later through the display-image endpoint.
  7. Retrieve and display the saved intake through the normal intake/history endpoints.

Did this page help you?