Skip to content

🎯 Tutorial: Personalizing Product Matching with Open Food Facts Attributes API#

Objective: Leverage the Open Food Facts API to dynamically personalize product recommendations based on user preferences using attributes and attribute_groups, avoiding hardcoding logic, and preserving user privacy


Core Concepts#

What are Product Attributes?#

Product attributes describe key characteristics and compliance information about food products, such as:

  • nutriscore
  • nova-group
  • labels (e.g. "organic", "fair-trade")
  • ingredients_analysis (e.g. "palm-oil-free", "vegan")
  • allergens

Note: We have experimental yet limited support for cosmetics, pet food and other products.

Why Use the /attribute_groups endpoint?#

The /attribute_groups endpoint provides the taxonomy and metadata needed to dynamically generate:

  • Matching logic
  • Preference UI
  • Labels, icons, descriptions, scores, etc.

Avoid hardcoding. Future-proof your app.

πŸ“˜ Reference: https://openfoodfacts.github.io/openfoodfacts-server/api/ref-v2/#get-/api/v2/attribute_groups πŸ“˜ Concepts: https://wiki.openfoodfacts.org/Product_Attributes


Prerequisites#

  • REST client (Postman, curl, JS/TS, Python requests, etc.)
  • Basic understanding of JSON and REST APIs
  • A list of user preferences (e.g. wants organic, avoids palm oil, prefers NutriScore A/B)

πŸš€ Step-by-Step Guide#


βœ… STEP 1 β€” Retrieve the attribute taxonomy#

GET https://world.openfoodfacts.org/api/v2/attribute_groups

Response Sample:#

{
  "attribute_groups": [
    {
      "id": "nutriscore",
      "name": "Nutri-Score",
      "attributes": [
        {
          "id": "nutriscore-a",
          "name": "Nutri-Score A",
          "match": 1,
          "icon_url": "https://.../nutriscore-a.svg"
        },
        ...
      ]
    },
    ...
  ]
}

🧩 Use this to dynamically build UI filters and assign matching scores.


βœ… STEP 2 β€” Define user preferences#

Example user preferences (in your code):

{
  "preferred_attributes": ["nutriscore-a", "labels-organic", "ingredients-analysis-palm-oil-free"],
  "avoided_attributes": ["labels-gluten-free"]  // optional if user has no dietary constraint
}

βœ… STEP 3 β€” Fetch product(s) with attributes#

Use attribute_groups in the fields parameter.

GET https://world.openfoodfacts.org/api/v2/product/3700214614266?fields=product_name,code,attribute_groups

Response Sample:#

{
  "product": {
    "product_name": "Organic Apple Juice",
    "code": "3700214614266",
    "attribute_groups": [
      {
        "id": "labels",
        "attributes": [
          {
            "id": "labels-organic",
            "status": "present",
            "match": 1
          },
          {
            "id": "labels-gluten-free",
            "status": "not_present",
            "match": 0
          }
        ]
      },
      {
        "id": "nutriscore",
        "attributes": [
          {
            "id": "nutriscore-a",
            "status": "present",
            "match": 1
          }
        ]
      }
    ]
  }
}

βœ… STEP 4 β€” Match products to preferences#

Matching algorithm (simplified):#

Here's the scoring algorithm in Javascript: https://github.com/openfoodfacts/openfoodfacts-server/blob/main/html/js/product-search.js You can adapt it to your programming language

πŸ’‘ Use this score to rank products.


βœ… STEP 5 β€” Match lists of products (batch processing)#

Use the /api/v2/search endpoint with the fields=attribute_groups query to fetch multiple products efficiently:

GET https://world.openfoodfacts.org/api/v2/search?code=3700214614266,3274080005003,3017620429484&fields=product_name,code,attribute_groups

Parse the products array and apply the match_product() function to each item to build a personalized list.


πŸ”„ Going Further: Dynamic UIs#

  • Use the /attribute_groups data to generate user-facing preference selectors dynamically.
  • Use match field to build "smart filters" based on what Open Food Facts knows.
  • Internationalization: retrieve name, description, icon_url in the user’s language (via lc=fr, lc=en, etc.)

βœ… Final Example: Personalized Product Matching Pipeline#

flowchart TD
  A[User Preferences] --> B[Load attribute_groups]
  B --> C[Build filter UI]
  A --> D[Fetch product list with attribute_groups]
  D --> E[Run matching algorithm]
  E --> F[Return sorted product list]

πŸ§ͺ Test URLs#


πŸ“Œ Key Benefits#

βœ… Future-proof: Your app adapts automatically to new attributes βœ… Customizable: Users define what matters to them βœ… International: Attributes are localized and translatable βœ… Scalable: Works with individual products or entire lists


πŸ€– Bonus: Ready-to-Use SDKs and Wrappers#

Want to speed things up? Use one of the Open Food Facts SDKs or contribute your own!

Elsewhere#

  • Fuller documentation available at https://wiki.openfoodfacts.org/Product_Attributes