Unified Food Search

Search dishes, ingredients, favorites, custom recipes and stored barcode products through one normalized interface. Designed to build unified food pickers for manual reporting and food confirmation workflows.

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

Unified Food Search provides a single normalized search interface for the different food sources that can be used when creating or confirming an intake.

Instead of querying dishes, ingredients, favorites and custom recipes independently and merging their different response formats on the client, you can use
GET /v2/food/search
to retrieve them through one common structure.

The endpoint currently supports these top-level food types:

  • dish — a regular LogMeal dish.
  • ingredient — a regular LogMeal ingredient that can be used to build an ingredient-only food item.
  • favorite — a saved favorite belonging to the target APIUser.
  • custom_recipe — a custom recipe available to the target user’s APICompany.
  • barcode_food_item — a previously resolved barcode product stored in LogMeal.

Each result contains both a type and an id.

The id is only unique within its own food type, so clients should always store and use type and id together.

For example, dish with id=123 and favorite with id=123 are different resources, even though they share the same numeric ID.

When a search result is later used in endpoints such as POST /v2/intake/manualInput/\{userId\} or POST /v2/image/confirm/dish, the type tells the API how the corresponding id must be interpreted.


When to Use It / Outcomes

Use Unified Food Search when:

  • You want to build one food picker instead of separate selectors for dishes, ingredients, favorites and custom recipes.
  • Users need to compose a manual mixed intake containing different kinds of foods.
  • Users need to confirm or correct an existing image intake with regular dishes, custom foods or previously saved resources.
  • You need the backend to apply the correct ownership and company restrictions for favorites and custom recipes.
  • You want all selected food sources to participate in one common ranking and pagination process.
  • You want food names returned using LogMeal’s localized language support.

Output: a normalized JSON response containing:

  • food_items: the globally ranked results for the requested page.
  • offset: the applied global offset.
  • limit: the requested page size.
  • total: the total number of matches before pagination.

Each item includes:

  • type
  • id
  • name
  • image_url

Depending on the food type, additional information such as default_quantity, unit, barcode and cooking_measures may also be returned.

Example:

{
  "food_items": [
    {
      "type": "dish",
      "id": 123,
      "name": "Apple pie",
      "image_url": null,
      "default_quantity": 150,
      "unit": "g"
    },
    {
      "type": "favorite",
      "id": 2124166,
      "name": "Apple breakfast",
      "image_url": "https://..."
    },
    {
      "type": "ingredient",
      "id": 388,
      "name": "Apple",
      "image_url": null,
      "default_quantity": 100,
      "unit": "g"
    }
  ],
  "offset": 0,
  "limit": 20,
  "total": 3
}

Feature-Specific Details

Supported Food Types

The supported top-level food types can be retrieved dynamically through
GET /v2/food/types.

Its response also indicates which types require non-empty search text.

Currently:

TypeSearch text requiredPurpose
dishYesRegular LogMeal dishes
ingredientYesRegular LogMeal ingredients
favoriteNoSaved favorites owned by the target APIUser
custom_recipeNoCustom recipes belonging to the target APIUser's APICompany
barcode_food_itemYesBarcode products already stored in LogMeal

barcode_ingredient is not a search result type.

It is a nested ingredient type used inside the unified intake contract when a barcode product is added as an ingredient of another food item.


Search Text

The query parameter is required whenever the requested types include:

  • dish
  • ingredient
  • barcode_food_item

For example:

GET /v2/food/search?query=apple&types=dish,ingredient

Favorites and custom recipes can be browsed without text:

GET /v2/food/search?types=favorite,custom_recipe

If types is omitted, all supported food types are selected. Because that includes types requiring search text, a query must also be provided.


Global Ranking

Results from all requested food types are merged into one common ranking.

Text matches are ordered by:

  1. exact match;
  2. prefix match;
  3. partial match.

Favorites and custom recipes receive a small priority boost only when their text-match quality is the same.

For example, an exact dish match still appears before a favorite that only matches by prefix.

The order supplied in types does not determine the result order.

For example:

GET /v2/food/search?query=apple&types=favorite,dish

and:

GET /v2/food/search?query=apple&types=dish,favorite

use the same global ranking rules.


Global Pagination

Pagination is performed after results from the requested food sources have been merged and ranked.

Conceptually:

Dishes ──────────────┐
Ingredients ─────────┤
Favorites ───────────┤
Custom recipes ──────┼──► Global ranking ─► offset / limit ─► food_items
Barcode products ā”€ā”€ā”€ā”€ā”˜

This means offset and limit refer to the complete combined result set, not to each food source independently.

total represents the number of matching results before this global pagination is applied.

The default pagination values are:

limit = 20
offset = 0

and limit can contain a maximum of 100 results.


Private Foods & APIUserManager Searches

Favorites and custom recipes depend on the target APIUser.

For šŸ”“ APIUser tokens, the user’s own context is used automatically.

For šŸ”µ APIUserManager tokens, user_id must be provided:

GET /v2/food/search?types=favorite,custom_recipe&user_id=1234

The manager must have access to that APIUser.

This target user determines:

  • which favorites are visible;
  • which APICompany is used to retrieve custom recipes.

This allows managers to build the same food picker that the managed APIUser would see while preserving resource ownership and company boundaries.


Localized Food Names

Unified Food Search supports LogMeal’s standard language resolution.

You can provide the language parameter where required:

GET /v2/food/search?query=apple&types=dish,ingredient&language=spa

Localized names are returned when translations are available.

If the language is omitted, the standard API language resolution is used.

See Multi-language Responses & Localized Food Names for more information.


Barcode Products

barcode_food_item searches barcode products that have already been stored in LogMeal.

They can be matched using:

  • their stored product name;
  • their barcode value.

For example:

GET /v2/food/search?query=8410376026962&types=barcode_food_item

Searching barcode products is different from scanning or resolving a new barcode.

If the product has not yet been resolved, use
POST /v2/barcode_scan/{barcode_id}
first.

The returned barcode dish_id represents the corresponding BarcodeClass GeneralClass ID and can then be used as a barcode_food_item in the unified intake contract.


Cooking Measures

Set:

cooking_measures=true

to include available cooking-measure IDs in each result where supported.

For example:

GET /v2/food/search?query=rice&types=dish,ingredient&cooking_measures=true

Regular dishes, ingredients and custom recipes may provide available cooking measures.

Favorites can contain multiple independent food items, so they do not expose one aggregate cooking measure and return an empty list.

Barcode food items currently use their stored OpenFoodFacts serving or weight and also return an empty cooking-measures list.


Using Search Results in an Intake

The normalized type and id returned by Unified Food Search can be used directly by the unified mixed-intake contract.

For example, a search result:

{
  "type": "dish",
  "id": 123,
  "name": "Chicken curry"
}

can become:

{
  "type": "dish",
  "id": 123,
  "quantity": 250
}

inside a manual intake.

A favorite result:

{
  "type": "favorite",
  "id": 2124166,
  "name": "Usual lunch"
}

can be submitted as:

{
  "type": "favorite",
  "id": 2124166
}

The same normalized contract is used by:

  • POST /v2/intake/manualInput/{userId}
  • POST /v2/image/confirm/dish

This allows the same food-picker component to be reused both for manually reporting food and for correcting an image-based intake.


Related Endpoints

Search contract

  • GET /v2/food/types → šŸ”“ šŸ”µ Returns the supported unified food types and identifies which ones require search text.
  • GET /v2/food/search → šŸ”“ šŸ”µ Searches and normalizes dishes, ingredients, favorites, custom recipes and stored barcode products.

Use selected foods

Barcode resolution

  • POST /v2/barcode_scan/{barcode_id} → šŸ”“ Resolves a barcode product without creating an intake. Use this flow when a barcode product is not already available through Unified Food Search.

Underlying catalogs


Typical Workflow

A common unified food-picker workflow is:

  1. Call GET /v2/food/types to retrieve the currently supported food types.
  2. Let the user enter search text or browse favorites/custom recipes.
  3. Call GET /v2/food/search with the required types, query, pagination and language parameters.
  4. Keep both type and id for every selected result.
  5. Allow the user to combine different result types in the same intake.
  6. Submit the selected foods through:
  7. If the user scans a barcode that is not available in search, resolve it through POST /v2/barcode_scan/{barcode_id} and normalize it as barcode_food_item.

Related Use Cases

Unified Food Search is especially useful for:

  • Building one reusable food picker for manual reporting and image confirmation.
  • Creating heterogeneous intakes containing regular dishes, individual ingredients, favorites, custom recipes and barcode products.
  • Allowing APIUserManagers to compose or correct food intakes in the context of a managed APIUser.
  • Building multilingual food-selection interfaces while keeping stable IDs independent from localized names.

Did this page help you?