Open Food Facts Scraper - Barcode, Nutrition, Allergens avatar

Open Food Facts Scraper - Barcode, Nutrition, Allergens

Pricing

from $1.00 / 1,000 run start fees

Go to Apify Store
Open Food Facts Scraper - Barcode, Nutrition, Allergens

Open Food Facts Scraper - Barcode, Nutrition, Allergens

Look up food products by EAN/UPC barcode or search by category, brand, label, country or Nutri-Score. Returns ingredients, allergens, additives, nutrition per 100g, Nutri-Score, NOVA and Eco-Score from the Open Food Facts open database.

Pricing

from $1.00 / 1,000 run start fees

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Open Food Facts Scraper

Look up food products by barcode, or search a whole category, brand, label or country. You get the ingredient list, the declared allergens, the additives, the nutrition table per 100g, and the three scores people actually filter on: Nutri-Score (A-E), NOVA (processing level 1-4) and Eco-Score.

Open Food Facts is an open database of food products, contributed the way Wikipedia is and published under an open licence. This Actor reads its public API rather than scraping the site, so it is fast, stable and returns far more per product than the rendered page shows.

The barcode is the point

Every product is addressed by its EAN/UPC. That is an exact join key, not a fuzzy name match, and it is the same key the retail scrapers return.

So the workflow this Actor is built for is: scrape prices somewhere, put the barcodes in here, get the food data back. No name matching, no guessing which "Coca-Cola 330ml" is which. Feed it a list of barcodes and every row comes back keyed on the barcode you supplied.

barcodes: ["5000112548167", "737628064502"]

That returns Coca-Cola Light (Nutri-Score C, NOVA 4) and a Thai peanut noodle kit (Nutri-Score D, 385 kcal/100g, allergens: peanuts, sesame seeds, soybeans).

Or search instead

Leave the barcodes empty and filter:

FieldExampleWhat it does
categoriesbreakfast-cerealsEverything in a category (27,046 matches)
brandsnestleOne brand's catalogue
labelsorganic, vegan, gluten-freeProducts carrying a label
countriesnetherlandsProducts sold in a market
storeslidl, albert-heijnProducts a retailer carries
nutrition_gradesaOnly Nutri-Score A products
allergensglutenProducts declaring an allergen

Filters combine. labels: organic plus countries: netherlands returns 4,064 matches. Use the tag form with hyphens, lower case.

What comes back

Per product:

  • Identity: barcode, product_name, generic_name, brands, quantity, serving_size, packaging
  • Composition: ingredients_text, allergens, traces, additives (E-numbers), origins
  • Scores: nutriscore_grade A-E, nova_group 1-4, ecoscore_grade A-E
  • Nutrition per 100g: energy_kcal_100g, fat_100g, saturated_fat_100g, carbohydrates_100g, sugars_100g, fiber_100g, proteins_100g, salt_100g, sodium_100g
  • Classification: categories, labels, countries, stores
  • Images: image_url, plus separate photos of the ingredient list and the nutrition table, which is what you want if you are checking a claim against the pack
  • completeness: how filled-in the record is, 0 to 1

Tags arrive from the API language-prefixed (en:gluten). They are returned stripped and readable (gluten), so they join cleanly.

Two honest notes about the data

is_stub tells you when a record is empty. Open Food Facts contains barcodes that somebody scanned and nobody ever filled in. Those come back with is_stub: true and a null product_name rather than being dropped, because when you are joining on barcodes there is a real difference between "this product is not in the database" and "it is in the database but empty". The run summary counts them.

Coverage varies by country and brand. This is volunteer-contributed open data, not a commercial catalogue. European food products, and French ones in particular, are covered far better than most. A missing product is a gap in the database, not a failure of the scraper, and the Actor says which of the two it is: an unknown barcode returns a not_found error naming that barcode, never a row of nulls.

About the intermittent 503s

Open Food Facts is a non-profit running on donated infrastructure, and its API returns HTTP 503 intermittently and without much pattern. Measured while building this: page_size=50 failed on a query where page_size=100 succeeded seconds earlier, and page 2 failed on two different network exits right after page 1 came back fine.

Two things this Actor does about that:

  1. Every request is retried with backoff (retries, default 4). Most 503s clear on the next attempt.
  2. A 503 is never parsed as an empty result. It arrives as a 22 KB HTML error page, and a scraper that reads it as JSON would report "this category has no products" — a confident wrong answer, on a run that looks successful. Non-JSON responses are retried and then reported as an explicit error, with the rows already collected returned intact.

If a page fails mid-pagination, you get the rows up to that point plus an error saying where it stopped. Partial and honest beats complete and wrong.

Input reference

FieldTypeDefault
barcodeslist of EAN/UPC strings—
categoriescategory tagbreakfast-cereals
brands, labels, countries, stores, allergenstag string—
nutrition_gradesa-eany
limit1-5000100
retries1-84

Give at least one barcode, a category, or one filter. An empty input is rejected with a message rather than walking the whole database.

Licence and attribution

Open Food Facts data is published under the Open Database License (ODbL). If you redistribute it you inherit that obligation, including attribution and share-alike on derived databases. The product photos carry their own licences. Check the Open Food Facts terms before republishing; using the data internally for analysis or enrichment is straightforward.