# Food Product Data — Barcodes, Nutrition, Allergens (`dalbian/food-product-data`) Actor

Look up packaged food by barcode or search by name, brand, category and country. Ingredients, allergens, nutrition per 100g, Nutri-Score, NOVA grade, additives and labels from Open Food Facts.

- **URL**: https://apify.com/dalbian/food-product-data.md
- **Developed by:** [Benjamin Jerez](https://apify.com/dalbian) (community)
- **Categories:** E-commerce, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 search runs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Food Product Data — Barcodes, Nutrition, Allergens

Look up packaged food and drink by **barcode**, or search by name, brand, category, country and Nutri-Score. Returns ingredients, allergens, full nutrition per 100 g, the Nutri-Score and NOVA processing grade, additives, labels, packaging and origin.

From **Open Food Facts**, the collaborative database that sits behind most nutrition apps — around three million products, published under an open licence you are allowed to build on.

### A barcode lookup

`3017620422003`:

| Field | Value |
| --- | --- |
| `productName`, `brands` | Nutella · Ferrero |
| `nutriScore`, `novaGroup` | **E** · 4 (ultra-processed) |
| `energyKcalPer100g`, `sugarsPer100g` | 539 · 56.3 g |
| `allergens` | milk, nuts, soybeans |
| `highIn` | fat, saturated fat, sugars |
| `additiveCount`, `isVegan` | 2 · no |

### Searching rather than scanning

Give a search term and the filters narrow it: brand, category, country of sale, label (organic, gluten-free, fair-trade, vegan) and Nutri-Score. Filters combine with AND.

Searching *chocolate cereal* in France returns Cruesli Chocolat Noir, Nature Valley Crunchy Oats & Dark Chocolate and LU Grany — 613 matches, all genuinely on topic. Add `nutriScoreFilter: a` to see how few of them there are.

Leave the search term empty and use filters alone to pull a whole category or a brand's full range.

### The two scores worth understanding

**Nutri-Score** grades nutritional quality from A to E, weighing sugar, salt, saturated fat and energy against fibre, protein, fruit and vegetables. It is what appears on packs across much of Europe.

**NOVA** is different and often more revealing: it grades how *processed* a food is, from 1 (unprocessed) to 4 (ultra-processed). A product can be Nutri-Score A and NOVA 4. `isUltraProcessed` exposes the NOVA 4 flag directly, because it is the single field most nutrition products filter on.

Alongside them, `highIn` lists whichever of fat, saturated fat, sugars and salt the product is officially high in, and `additiveCount` gives the number of E-numbers in the ingredients.

### Who uses this

Nutrition and diet apps that need a product catalogue they can legally ship. Retailers and distributors auditing an assortment for allergens or additives. Researchers studying food composition across markets. Anyone building a barcode scanner who does not want to license a commercial catalogue per lookup.

### On data quality

Open Food Facts is **contributor-built**, which has two consequences worth planning for.

Coverage is uneven: excellent in France and much of Europe, thinner elsewhere, and a barcode from a small local producer may simply be absent. A missing product is reported as such rather than guessed at.

Completeness varies per product. A contributor may have photographed the pack without transcribing the nutrition table. `dataCompleteness` gives Open Food Facts' own 0-to-1 estimate for each product, so you can filter out half-finished entries before relying on them.

### Licence

Product data is published under the **Open Database License (ODbL)**: you may use, adapt and sell products built on it, provided you credit Open Food Facts and keep any derived *database* under the same licence.

Product photographs are licensed separately by their contributors and are **not** returned by this Actor, so nothing here carries an image licence you would have to honour.

### Frequently asked

**Why does a product I scanned come back missing?**
Because no contributor has added it yet. You can add it yourself on openfoodfacts.org, and it will be available to everyone — including this Actor — immediately.

**Why are nutrition values empty on some products?**
Because the nutrition table was never transcribed. `dataCompleteness` tells you how complete the entry is before you rely on it.

**Are Nutri-Score and NOVA official?**
Nutri-Score is an official front-of-pack system in several European countries; the value here is the one Open Food Facts computes from the declared composition, which matches the pack when the pack carries one. NOVA is an academic classification, not a regulatory label.

**Can I get every product in a category?**
Yes — leave the search term empty, set the category filter, and raise `maxResultsPerSearch`.

# Actor input Schema

## `barcodes` (type: `array`):

EAN or UPC barcodes, one per line, exactly as printed on the pack. This is the precise lookup — one barcode is one product in one format.

## `searchTerms` (type: `array`):

Product or brand names to search for, one per line. Leave empty and use the filters below alone to browse a whole category or brand.

## `brandFilter` (type: `string`):

Keep only products of this brand, such as danone or lu. Filters combine with AND, so a brand plus a category returns only what satisfies both.

## `categoryFilter` (type: `string`):

Keep only this category, such as breakfast-cereals, yogurts or plant-based-foods. Categories nest, so a broad one returns everything beneath it.

## `countryFilter` (type: `string`):

Keep only products sold in this country, such as france or germany. The same product can be listed in several.

## `labelFilter` (type: `string`):

Keep only products carrying this label, such as organic, fair-trade, gluten-free or vegan.

## `nutriScoreFilter` (type: `string`):

Keep only products with this Nutri-Score. A is the best nutritional profile, E the worst.

## `maxResultsPerSearch` (type: `integer`):

How many products to return per search term or filter set. Barcode lookups are unaffected.

## Actor input object example

```json
{
  "barcodes": [
    "3017620422003"
  ],
  "maxResultsPerSearch": 100
}
```

# Actor output Schema

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "barcodes": [
        "3017620422003"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dalbian/food-product-data").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "barcodes": ["3017620422003"] }

# Run the Actor and wait for it to finish
run = client.actor("dalbian/food-product-data").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "barcodes": [
    "3017620422003"
  ]
}' |
apify call dalbian/food-product-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dalbian/food-product-data"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/BKeOaLyawYMYyKO1w/builds/QJO5czsGG2k1C0PqD/openapi.json
