Open Food Facts Product Lookup — Ingredients & Nutri-Score API
Pricing
from $2.40 / 1,000 successful lookups
Open Food Facts Product Lookup — Ingredients & Nutri-Score API
Look up food products by barcode against Open Food Facts' free, crowdsourced database of 3M+ products. Get name, brand, ingredients, allergens, Nutri-Score, Eco-Score, NOVA group, and per-100g nutrition facts. Pay only for barcodes that resolve.
Pricing
from $2.40 / 1,000 successful lookups
Rating
0.0
(0)
Developer
Adrian Voss
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Open Food Facts Product Lookup
Look up any food product by barcode (GTIN/UPC/EAN) against the free, crowdsourced Open Food Facts database — ingredients, allergens, Nutri-Score, NOVA processing group, Eco-Score, and full per-100g nutrition facts. No API key and no scraping: this calls the official public API directly, so you get the same record the Open Food Facts app reads.
Who it's for
Built for anyone who needs real product data behind a barcode without a paid database subscription. Food-app and diet-tracker builders use it to turn a user's barcode scan into Nutri-Score, NOVA group and full nutrition facts on the spot. Import and retail compliance teams screen a supplier's SKU list for undeclared allergens and additives before it ever reaches a shelf. Comparison-shopping and price-tracking tools attach a name, brand and image to a barcode list pulled from POS or supplier data — the boring enrichment step that turns a list of numbers into something a shopper recognizes.
Why this one
- The official public API, not a scrape. Open Food Facts publishes a free product API and this actor calls it directly — no HTML parsing to break, no key to request.
- You don't pay for barcodes it doesn't know. A barcode that isn't in the database, or
isn't a valid GTIN, comes back
found: falseand is never billed. - Everything on the label in one row. Ingredients, allergens, additives, labels, Nutri-Score, NOVA group, Eco-Score and eight per-100g nutrition figures — one lookup, not five.
- Separators are stripped for you.
0737628064502,737628064502and a barcode pasted with spaces or hyphens all resolve to the same product. - Stably-named fields. Column names are frozen between runs, which matters if an AI agent or a Clay column reads the schema once and keeps using it.
What you get
One row per input barcode, with field names frozen between runs — a schema mapped once by an agent or a Clay column keeps working.
| Field | Type / format | Description |
|---|---|---|
query | text | The barcode exactly as submitted, before separators are stripped. |
found | boolean | Whether the barcode resolved to a product. Gates billing — false rows are never charged. |
status | text | OK, NOT_FOUND (barcode not in the database), or BAD_FORMAT (not an 8–14 digit GTIN). |
barcode | text | The normalized barcode as Open Food Facts stores it. |
name | text | Product name, falling back to the generic name when the branded one is blank. |
brands | text | Brand string as entered by contributors — may list several, comma-separated. |
categories | array | Category path, split into separate entries. |
quantity | text | Pack size as printed — e.g. 155 g. |
nutriScore | text | Nutri-Score grade A–E, uppercased. null when not computed. |
novaGroup | number | NOVA processing group, 1 (unprocessed) to 4 (ultra-processed). |
ecoScore | text | Eco-Score grade, uppercased. Often UNKNOWN outside the EU. |
ingredientsText | text | Full ingredients list as printed on the packaging. |
allergens | array | Declared allergens, with the en: language prefix stripped. |
additives | array | Additive codes present — e.g. e330. |
labels | array | Certifications and claims — Organic, Vegan, No gluten. |
countries | array | Markets the product is recorded as being sold in. |
nutrition | object | Per-100g figures: energyKcal100g, fat100g, saturatedFat100g, carbohydrates100g, sugars100g, fiber100g, proteins100g, salt100g. |
imageUrl | link | Front-of-pack product photo. |
scrapedAt | date (ISO 8601) | When the lookup ran. |
Price
$4 per 1,000 barcodes, plus a $0.005 start fee. Misses (found:false) are never charged.
You're billed per barcode that resolves to a product. A barcode the database doesn't know, or one that isn't a valid GTIN, costs nothing no matter how many are in the list. Run 1,000 barcodes and, at the live FREE-tier price, that's roughly $4 if every one resolves — cheaper in practice, since misses cost nothing, and cheaper again on paid Apify tiers. No monthly fee runs whether or not you use it that month.
How to use
- In the Apify Console. Open the actor page and click Start — the
barcodesfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~openfoodfacts-product-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"barcodes":["0737628064502"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
- Paste your barcodes into
barcodes— digits only, with or without a leading zero. - Run the actor. Each barcode is looked up against the Open Food Facts product API, in
parallel up to
maxConcurrency. - Read the dataset. Each row carries the full product record, or
found: falseif the barcode isn't in the database. - Turn on
onlyFoundif you want the misses dropped from the output entirely.
Common ways teams use this:
- Screen a catalogue for allergens or additives before listing or importing it, by
filtering rows on
allergensandadditives. - Pull per-100g nutrition in bulk for a private-label range or a comparison app.
- Enrich a barcode scan with Nutri-Score and NOVA group instantly inside a health or diet product.
- Attach names, brands and images to a barcode list exported from POS or supplier data.
- Check which markets a product is sold in using
countriesbefore planning a launch.
Input
{"barcodes": ["0737628064502"]}
One GTIN/UPC/EAN barcode per line, digits only. Accepted formats: 0737628064502, 737628064502.
{"barcodes": ["0737628064502", "737628064502"],"testRun": false,"onlyFound": false,"maxConcurrency": 5}
barcodes is your list of GTIN/UPC/EAN codes — separators are stripped automatically, so
spaces and hyphens are fine. Turn on testRun to try the list against just the first five
barcodes before committing to the full batch. onlyFound drops miss rows from the output,
maxResults stops the run early once that many products have been found, includeKeywords
and excludeKeywords filter rows by content, and columns picks which fields come back —
useful for keeping a Clay table narrow.
Sample output
| query | found | status | name | barcode | brands | categories | quantity | nutriScore | novaGroup | ecoScore | ingredientsText | allergens | additives | labels | countries | nutrition | imageUrl | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0737628064502 | true | OK | Thai peanut noodle kit includes stir-fry rice noodles & thai peanut seasoning | 0737628064502 | Simply Asia, Thai Kitchen | ["Cereals and their products","Noodles","Rice Noodles"] | 155 g | D | 4 | UNKNOWN | Rice Noodles (rice, water), seasoning packet (peanut, sugar, salt, corn starch, spices [chili, cinnamon, pepper, cumin, clove], hydrolyzed soy protein, green onions, citric acid, peanut oil, sesame oil, natural flavor). | ["peanuts","sesame seeds","soybeans"] | ["e330"] | ["No gluten","Vegan"] | ["France","United States"] | {"energyKcal100g":385,"fat100g":7.69,"saturatedFat100g":1.92,"carbohydrates100g":71.15,"sugars100g":13.46,"fiber100g":1.9,"proteins100g":9.62,"salt100g":0.72} | https://images.openfoodfacts.org/images/products/073/762/806/4502/front_en.6.400.jpg | 2026-08-23T21:04:47.132Z |
That table lists every available column. A single row reads like this:
{"query": "0737628064502","found": true,"status": "OK","barcode": "0737628064502","name": "Thai peanut noodle kit","brands": "Simply Asia, Thai Kitchen","categories": ["Cereals and their products", "Noodles", "Rice Noodles"],"quantity": "155 g","nutriScore": "D","novaGroup": 4,"ecoScore": "UNKNOWN","allergens": ["peanuts", "sesame seeds", "soybeans"],"additives": ["e330"],"labels": ["No gluten", "Vegan"],"countries": ["France", "United States"],"nutrition": { "energyKcal100g": 385, "fat100g": 7.69, "sugars100g": 13.46, "salt100g": 0.72 },"scrapedAt": "2026-08-23T21:04:47.132Z"}
A barcode the database doesn't know still returns a row, and is never charged:
{"query": "0000000000000","found": false,"status": "NOT_FOUND","message": "No product is registered under this barcode in Open Food Facts.","scrapedAt": "2026-08-23T21:04:47.132Z"}
Failed barcodes stay in the dataset by default rather than disappearing — useful for spotting
a batch of transcription errors versus barcodes that genuinely aren't registered. Set
onlyFound if you'd rather not see them.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~openfoodfacts-product-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"barcodes":["0737628064502"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~openfoodfacts-product-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"barcodes":["0737628064502"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~openfoodfacts-product-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"barcodes":["{{barcode}}"]}, mapping the row's barcode into the barcodes array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Open Food Facts API — Barcode to Nutri-Score & Allergens" — the agent will find and run this actor.
Tips
- Send the barcode exactly as scanned. Leading zeros are preserved and separators stripped, so you rarely need to normalize a list before running it.
- Treat
ecoScoreas EU-centric. It's frequentlyUNKNOWNfor products sold outside Europe — don't build a filter that silently drops those rows. - Use
columnsto keep a Clay table narrow. The full record is wide; picking six fields makes the output far easier to map into a spreadsheet. - Check
countriesbefore trusting a nutrition figure for your market. The same brand can have a different recipe per country, and the record reflects whichever pack was contributed. - Run
testRunfirst on a big list. Five barcodes will tell you whether your codes are the right format before you commit the whole batch.
vs. alternatives
| What it costs | What you get | Trade-off | |
|---|---|---|---|
This actor (openfoodfacts-product-lookup) | $4 per 1,000 resolved barcodes (less on paid tiers), $0.005 actor start, nothing for a barcode the database doesn't know | The full Open Food Facts record — ingredients, allergens, additives, labels, Nutri-Score, NOVA, Eco-Score and per-100g nutrition — as one flat row | Coverage is only as good as Open Food Facts itself: crowdsourced, strongest in the EU, thinnest on niche and own-brand products |
| burbn/barcode-lookup (122 users) | $0.02 per result, $0.01 start | A general barcode resolver across product types, not just food | Five times the per-row price, and broader rather than deeper — no Nutri-Score, NOVA or per-100g nutrition |
| Open Food Facts' own API | Free | The same JSON | It is the same JSON. This handles the barcode normalization, the retries, the concurrency ceiling and the flattening, and hands you a table instead of nested objects. |
| A commercial GS1 / GDSN feed | Four figures a year and up | Authoritative manufacturer-supplied data with guaranteed coverage | If you need contractual accuracy for regulated labelling, buy the commercial feed. This is a free, crowdsourced source and should be treated as such. |
(Prices for the tools above are their August 2026 FREE-tier list prices — check their own pages before relying on a straight comparison.)
Coverage: what's in Open Food Facts
Open Food Facts is crowdsourced — anyone with the app can add or edit a product — which cuts both ways. It means millions of products are covered for free, but coverage tracks where the contributor community is strongest, not where products are sold. Packaged goods sold in the EU, and especially France where the project started, have the most complete records: full ingredients, all four scores, per-100g nutrition. Products sold only in smaller markets, store own-brands, and anything niche are more likely to have a thin record or no record at all.
Practically: expect nutriScore and ecoScore to be null more often outside Europe, expect
some barcodes not to resolve at all even for real products, and treat a found: false as "not
in this crowdsourced database" rather than "doesn't exist." For products where you need
guaranteed coverage — a specific retailer's own catalogue, for instance — this free source
won't get you there; a commercial GS1 feed will, at commercial prices.
FAQ
Do I need an Open Food Facts API key? No. The product API is free and public — this actor calls it directly, with no credentials required on your end.
How accurate and up to date is the data? Open Food Facts is crowdsourced and community-maintained, covering millions of products worldwide. Coverage and freshness vary by product and region — packaged goods sold in the EU, especially France where the project started, tend to have the most complete records. Treat it as a very good free source, not as a manufacturer-certified one.
What happens if a barcode isn't in the database?
You still get a row, with found: false and status: NOT_FOUND, so your output always has one
row per input — and you're never charged for it.
Can I run this against thousands of barcodes at once?
Yes. Turn on testRun first to sanity-check the list against five barcodes, then run the full
batch. maxConcurrency controls how many requests run in parallel.
Does this only work for US products?
No — it's a global database. Use countries on each result to see which markets a product is
actually recorded as being sold in.
Why is nutriScore or ecoScore empty on a product that clearly has one?
Both are computed by Open Food Facts, and only when enough of the underlying nutrition data has
been contributed. A sparse record produces a null grade rather than a guess.
Is the nutrition data per 100g or per serving?
Per 100g or 100ml, always — that's what the 100g suffix on each field means. Serving-size
figures aren't returned, so a per-portion number has to be derived from quantity.
Can I look up a product by name instead of barcode? No — this actor is barcode-keyed by design. Open Food Facts does offer text search, but it returns ranked guesses rather than one definite product, which is the wrong shape for a lookup that promises exactly one row per input.
Why do two barcodes for the same product return different data?
Because they're different pack records. A 200g jar and a 400g jar carry separate GTINs and are
contributed separately, so the nutrition may match while quantity, imageUrl and even
labels differ. Match on barcode, not on name.
Does the actor write anything back to Open Food Facts? No. It only reads. Nothing about your barcode list, your run, or your account is sent to the project — and no data is stored between runs on this side either.
What does novaGroup actually mean?
It's the NOVA food-processing classification, 1 to 4: 1 is unprocessed or minimally processed,
4 is ultra-processed. It's a processing measure, not a health score — nutriScore is the one
that grades nutritional quality.
Related actors
- GTIN/Barcode Lookup — barcode resolution across non-food product categories.
- Allegro Listing Lookup — live marketplace price and availability when you have a listing URL rather than a barcode.
- Shopify Store Lookup — live product catalogues for merchants running their own Shopify storefront.