L logiover
business · Jul 9, 2026 · 7 min read

How to Scrape Open Food Facts Nutrition & Barcode Data

Extract nutrition facts, Nutri-Score, NOVA group, ingredients and labels from Open Food Facts by category, brand or barcode — keyless JSON API, bulk pagination.

Open Food Facts is the largest open food database on the web — over 3 million products, community-contributed, with barcodes, ingredients, nutrition tables and Nutri-Score grades. It publishes everything through a free, keyless JSON API, which sounds like the hard part is solved. It isn’t. If you want all yogurts sold in France or every ultra-processed breakfast cereal, you’re facing paginated search endpoints, inconsistent field coverage across community entries, and a category taxonomy that expects slugs, not display names. This guide covers how the Open Food Facts API is structured, how to pull data in bulk without tripping over its quirks, and what the extracted records actually look like.

What’s worth extracting

Each product record carries 17 fields, grouped by what you’ll use them for:

  • Identitycode (the EAN/UPC barcode, your stable key), product_name, brands, categories (category tags), quantity (package size like “500 g”).
  • Health ratingsnutriscore_grade (a–e), nova_group (1–4 processing level, where 4 is ultra-processed).
  • Nutriments per 100genergy_kcal_100g, fat_100g, sugars_100g, salt_100g, proteins_100g.
  • Compositioningredients_text (the full ingredient list, often in the product’s local language).
  • Certification & marketlabels (organic, fair-trade, no-palm-oil and other quality tags), countries (where the product is sold).
  • Media & linksimage_url (front image) and url (the product’s Open Food Facts page).

For diet analysis you need the barcode, name, nutriscore, nova group and the five nutriments. For catalog enrichment, add the image URL and ingredients.

How the Open Food Facts API works

The actor talks to world.openfoodfacts.org — the official public API — across three endpoints matching its three modes.

Search mode hits /api/v2/search with category, brand and country filters, paginating in batches of 100 until it reaches maxResults. This is the workhorse for building datasets:

{
  "mode": "search",
  "categories": ["breakfast-cereals", "muesli"],
  "brands": ["Kellogg's"],
  "countries": ["united-states"],
  "maxResults": 1000
}

Category mode uses the dedicated /category/<slug>.json endpoint, which is slightly faster for straight category browsing but returns fewer fields than search.

Product mode fetches individual products by barcode via /api/v2/product/<barcode>.json — the fastest path when you already have a barcode list:

{
  "mode": "product",
  "barcodes": ["3017620422003", "5449000000996", "7613036020328"]
}

The critical detail is that filters expect slugs, not display names. You pass breakfast-cereals, not “Breakfast Cereals”; united-states, not “USA”. Country filters use English-language slugs regardless of where the product is sold. There is no HTML scraping here — every request returns clean JSON straight from the API.

Choosing a mode

The three modes trade breadth against depth, and picking the right one saves both time and cost:

  • Search is the default and the most flexible. Use it whenever you’re filtering by category, brand or country and want the full 17-field record per product. It’s the only mode that combines filters — categories and brands and countries together — which is how you get precise slices like “Kellogg’s breakfast cereals sold in the US.”
  • Category is a browse shortcut. It hits the dedicated per-category endpoint, which is marginally faster for pulling a whole category, but returns fewer fields than search. Reach for it when you want everything in one category and don’t need the tightest field set.
  • Product is the direct-lookup path. If you already hold a list of barcodes — say, your grocery inventory — this fetches each product individually with no pagination overhead. It’s the fastest per-item mode and the right choice for enrichment pipelines that start from known EANs/UPCs.

Most dataset-building work lives in search mode; category and product are the specialized tools for browsing and enrichment respectively.

Run the Open Food Facts Scraper on Apify — search by category, brand or country, or look up a barcode list, and export nutrition data to CSV or JSON. Keyless, no login.

The access reality

Open Food Facts is a nonprofit and the API is open and generous — there’s no key, no token expiry, and no aggressive rate limiting. That removes the usual scraping friction, but it introduces a different one: data completeness varies wildly because the database is community-contributed.

  • Nutrition fields are frequently null. Many products exist in the database with just a barcode and name because no contributor has filled in the nutrition table. Expect empty energy_kcal_100g, fat_100g and the rest for a meaningful slice of any broad query. Filter these out downstream (energy_kcal_100g is not null) before you compute averages.
  • Nutri-Score isn’t universal. nutriscore_grade is only computed for products where the data supports it and, historically, where the market context makes it relevant. Some products return an empty grade — drop them if you’re comparing grades head to head.
  • Ingredients are multilingual. ingredients_text comes back in whatever language the contributor entered, often the product’s origin country. If you need English, bias your query with a countries filter toward English-speaking markets, but don’t expect it to be perfect.
  • Popular categories are huge. Categories like “yogurts” or “beverages” hold tens of thousands of products. Set maxResults deliberately — an unlimited run on “beverages” is a large job.

Because the API doesn’t rate-limit hard, the actor still keeps concurrency modest (3 requests by default) to be a good citizen of a nonprofit resource. Datacenter proxy is sufficient; you never need residential IPs.

Example output

A single search-mode record for a real product:

{
  "code": "3017620422003",
  "product_name": "Nutella",
  "brands": "Ferrero",
  "categories": "Spreads, Sweet spreads, Chocolate spreads",
  "quantity": "400 g",
  "nutriscore_grade": "e",
  "nova_group": 4,
  "energy_kcal_100g": 539,
  "fat_100g": 30.9,
  "sugars_100g": 56.3,
  "salt_100g": 0.107,
  "proteins_100g": 6.3,
  "ingredients_text": "Sugar, palm oil, hazelnuts (13%), skimmed milk powder (8.7%)...",
  "labels": "no-gluten",
  "countries": "france, germany, united-kingdom, united-states",
  "image_url": "https://images.openfoodfacts.org/images/products/301/762/042/2003/front_en.497.400.jpg",
  "url": "https://world.openfoodfacts.org/product/3017620422003"
}

Who uses this

  • Nutritionists and dietitians building diet-comparison tools or client food-tracking systems on a maintained, free nutrition database.
  • Food-tech startups that need a nutrition backend without paying for a commercial data provider or maintaining their own crawler.
  • Data scientists and researchers analyzing food composition, ultra-processing prevalence (filter nova_group equals 4), or Nutri-Score distribution across brands and countries.
  • E-commerce and retail teams enriching product catalogs with nutrition facts, front images and ingredient lists keyed on barcode.
  • Journalists and public-health advocates studying food labeling, additive use and ultra-processed-food patterns with a reproducible dataset.
  • Grocery and delivery apps running a barcode list through product mode to attach nutrition data to their inventory.

Cost and effort: build vs. managed

The API is free and documented, so a one-off script is achievable. What eats time is the shape of the problem: paginating /api/v2/search correctly, normalizing the nested nutriments object into flat columns, mapping display names to the slugs the API actually wants, and handling the pervasive null fields without your pipeline choking. Then you own that code as the community re-tags products and the schema drifts.

The managed actor is pay-per-result — pennies per hundred records, scaling linearly. A 1,000-product category pull runs in roughly four to five minutes and costs a few cents. Because Open Food Facts has no proxy or anti-bot cost, the entire expense is just per-row plus a negligible start fee, which makes bulk category datasets genuinely cheap to assemble.

Common pitfalls

Source-specific things to get right:

  • Use slugs everywhere. The single most common mistake is passing “Breakfast Cereals” instead of breakfast-cereals. Check the Open Food Facts categories page for valid slugs before a big run.
  • Filter nulls before aggregating. Community data is incomplete. Averaging sugars_100g across a category without dropping nulls skews your numbers.
  • NOVA 4 is your ultra-processed filter. If you’re building an ultra-processed-food dataset, filter nova_group equals 4 — it’s the cleanest single signal in the record.
  • Nutri-Score coverage is partial. Don’t assume every product has a grade; branch your logic for the empty case.
  • Barcode mode skips misses silently. In product mode, a barcode that isn’t in the database is logged and skipped — your dataset contains only the barcodes that existed, so reconcile against your input list if completeness matters.
  • Brand and country filters are search-mode only. The brands and countries inputs apply in search mode. Category mode browses a single category endpoint and product mode looks up exact barcodes, so if you need to combine a category with a brand or market, you must use search.
  • Re-run for freshness. The database updates daily as contributors add products and corrections. A dataset from months ago will be missing new entries; schedule periodic re-runs for production use.

Wrapping up

Open Food Facts hands you a keyless, openly licensed food database — the access is the easy part. The real work is paginating the search endpoint, flattening nutriments, speaking the slug-based taxonomy, and absorbing the null-heavy nature of community data. If you need a quick lookup, hit the API directly. If you need a clean, filtered nutrition dataset by category, brand or barcode, delivered as a spreadsheet, a managed actor handles the plumbing for a fraction of a cent per row.

Open the Open Food Facts Scraper on Apify — one run yields a nutrition dataset of thousands of products with Nutri-Score, NOVA group, ingredients and labels, exportable to CSV, Excel or JSON. No API key, no login. Start on Apify’s free monthly credit.

Related guides