Food Barcode Nutrition & Allergen Lookup
Pricing
$2.00 / 1,000 products
Food Barcode Nutrition & Allergen Lookup
Food barcode nutrition and allergen lookup using Open Food Facts. Export packaged-food records as JSON with source links and data-license attribution; missing products yield error rows.
Pricing
$2.00 / 1,000 products
Rating
0.0
(0)
Developer
Grit
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Turn packaged-food barcodes into structured nutrition and allergen records with Open Food Facts source links and data-license attribution.
Supply a list of food barcodes. The actor calls the official public Open Food Facts v2 product API and saves a result or an error row for each selected entry. It retrieves packaged-food composition; openFDA recalls and adverse-event records are outside this actor's scope.
What it returns
| Field | Meaning |
|---|---|
barcode | OFF-normalized barcode string; null for malformed input |
status | ok for a usable product, otherwise error |
productName | Product name; falls back to the source's English name |
brand | Brand string as supplied by OFF; may contain multiple brands |
nutritionPer100g | Ten selected nutrient values from OFF's _100g fields; missing values are null |
nutriScore | Source Nutri-Score grade a through e, or null |
categoryTags | Source category tags; language prefixes are preserved |
allergenTags | Source allergen tags; null when unavailable |
traceTags | Source traces / may-contain tags; null when unavailable |
productUrl | Product page on Open Food Facts |
sourceUrl | Product API URL including the exact fields allowlist |
source | Open Food Facts |
attribution | Open Food Facts contributors |
license, licenseUrl | ODbL-1.0 database-license identifier and link |
contentsLicenseUrl | Database Contents License link |
error, errorMessage | Machine-readable error and short explanation; null on success |
Nutrition keys: energyKcal (kcal), energyKj (kJ), and fatG, saturatedFatG, carbohydratesG, sugarsG, fiberG, proteinG, saltG, sodiumG (grams). Values come from the source's standardized _100g fields, without estimating missing values or converting serving data. For liquids, OFF may use these fields for a 100 ml basis; check the package before comparing with solid foods. Sodium is expressed in grams, not milligrams.
Missing values are null, while a recorded zero stays zero. A returned empty allergen list means OFF reported no tags; it does not establish that the food is allergen-free. Check the package and manufacturer information for dietary decisions.
Dataset views cover products/allergens, nutrition, and sources/licenses. The run's key-value store also contains DATA_LICENSE and RUN_STATS records.
Input example
The Store prefill is:
{"barcodes":["3017620422003"],"maxItems":1}
| Input | Default / limits |
|---|---|
barcodes | Required non-empty array of strings; at most 1,000 entries; accepted lengths 8, 12, 13, 14 ASCII digits |
maxItems | Default 100; range 1-200; prefill 1; includes error rows |
concurrency | Fixed at 1 to preserve a shared request/charging limit |
Whitespace is trimmed. Barcodes follow OFF zero-prefix normalization: remove leading zeros, pad shorter codes to 8 or 13 digits as appropriate, and retain longer codes. Equivalent valid codes are deduplicated before the cap. Inputs are strings so leading zeros are not lost before processing. Check digits are not validated; a syntactically valid but absent barcode returns not_found.
Output example
This is an excerpt from the real prefill run; sample_output.json contains the full row, including category tags and source URL. Source values can change.
{"barcode": "3017620422003","status": "ok","productName": "Nutella","brand": "Nutella, Ferrero","nutritionPer100g": {"energyKcal": 539.0,"energyKj": 2252.0,"fatG": 30.9,"saturatedFatG": 10.6,"carbohydratesG": 57.5,"sugarsG": 56.3,"fiberG": 0.0,"proteinG": 6.3,"saltG": 0.107,"sodiumG": 0.0428},"nutriScore": "e","allergenTags": ["en:milk","en:nuts","en:soybeans"],"traceTags": [],"productUrl": "https://world.openfoodfacts.org/product/3017620422003","attribution": "Open Food Facts contributors","license": "ODbL-1.0","licenseUrl": "https://opendatacommons.org/licenses/odbl/1-0/"}
Pricing
Proposed pay-per-event price: $0.002 per product event ($2.00 for 1,000 successful products across appropriately sized runs). A usable product has a name or at least one supported nutrition value. Invalid inputs, duplicates, capped entries, missing products, empty records and failed lookups have no product charge. The actor checks the remaining event budget before processing and stops when the SDK signals the spending limit.
On 2026-10-06, the highest-user comparable found in the targeted Store searches was fortuitous_pirate/yuka-food-score, with 33 total users and a $0.0035 result event plus a $0.05 actor-start event. Our proposed result price is lower. Free alternatives also exist. Full prices, comparison scope, events and timestamped API receipts are in PRICING.md.
Pricing is a publication proposal and has not been configured on Apify. There is no custom startup event in this actor. The proposed platform actor-start price is zero; platform usage fees and any actual Console-configured event prices depend on the owner's publication settings. Local runs do not submit paid charges.
Limits and source behavior
- Fixed endpoint:
https://world.openfoodfacts.org/api/v2/product/{barcode}.json. - Requested fields:
code,product_name,product_name_en,brands,nutriments,nutrition_grades,categories_tags,allergens_tags,traces_tags. - Output is explicitly projected into the field table above. Photos, contributor/user fields, revision histories and raw API response dictionaries are excluded.
- Identifying User-Agent:
FoodBarcodeNutrition/1.0 (+https://apify.com/Grit-77). - One request at a time, with at least five seconds between starts, including retries. This stays below the currently documented 15 product reads/minute/IP for an isolated run. Avoid concurrent runs or other OFF requests on the same IP; this actor cannot coordinate other containers' traffic.
- Network failures, HTTP 429 and server errors receive at most three attempts with exponential backoff.
Retry-Afterseconds and dates are respected. If a requested cooldown exceeds five minutes, the run stops sending source requests and emits unchargedrate_limitedrows for remaining entries. - Permanent HTTP failures and invalid source responses become per-item errors. Input-level errors fail the run with a clear message. Storage and billing errors propagate so they cannot silently look successful.
- The source requests bulk exports for larger datasets. This actor caps each run at 200 entries and does no search, crawling or enumeration. OFF currently marks v2 deprecated but supported; this integration uses v2 as specified.
Attribution and database reuse
Contains information from Open Food Facts, contributed by Open Food Facts contributors. The database is available under ODbL 1.0 and its individual contents under the Database Contents License. Keep attribution and license links with exports and visible products that use this data.
When publicly redistributing the database or publicly using a derived database, preserve the ODbL notices and applicable share-alike terms. Under ODbL section 4.6, provide the machine-readable derived database or alterations as required; internet access to that copy must be free of charge. Combining or transforming records does not remove these obligations. Charging for the lookup service does not grant exclusive rights over OFF data. See OFF's license guidance and the full license for details. The notices also accompany rows, fixture provenance and the DATA_LICENSE record.
FAQ
Can I use this for recalls or adverse events? This actor covers packaged-food identity, nutrition and allergen tags. Use an appropriate openFDA integration for recall or adverse-event research.
Does it guarantee allergen safety? No. OFF data is community maintained and may be incomplete, inaccurate or outdated. Missing tags are unknown; they must not be turned into an allergen-free claim by downstream applications.
Why do barcodes sometimes change? OFF normalizes UPC/EAN zero-prefix aliases. For example, UPC 737628064502 becomes 0737628064502; both refer to one lookup.
What happens if a product is missing? An uncharged error row has error: "not_found". A found record without a name or supported nutrition has error: "empty_product".
Is an API key needed? OFF reads are public and use the actor's identifying User-Agent. No OFF API key or login is used. Apify-hosted execution uses the caller's normal Apify authorization.
Use with AI agents / MCP
After the owner deploys the actor, an AI agent can run it with the input object above and read the default dataset through the output schema's dataset link. Keep maxItems small and retain sourceUrl, attribution and license information in downstream records. Treat null nutrition and allergen fields as unknown.
The Apify MCP server exposes eligible deployed actors as tools. Connect your MCP client to https://mcp.apify.com, authorize through the supported flow, and select this actor using its actual deployed identifier. This local project has not been deployed or tested through MCP.
Example agent instruction: “Look up barcode 3017620422003 with maxItems 1. Return the supplied product composition and source link. Preserve attribution and license links. Do not infer allergen safety from missing data.”
Local development and verification
Dependencies are listed in requirements.txt; the provided shared venv already has them. No packages were installed into it.
Run from this actor directory using the prescribed interpreter:
C:/GritWork/earn/.venv/Scripts/python scripts/record_tests.py unitC:/GritWork/earn/.venv/Scripts/python scripts/record_tests.py liveC:/GritWork/earn/.venv/Scripts/python scripts/verify_local.pyapify validate-schema
verify_local.py sets APIFY_LOCAL_STORAGE_DIR, writes storage/key_value_stores/default/INPUT.json, runs python -m src without the Apify CLI, saves the real sample, and exercises fresh processes with repeated/different inputs and invalid/capped cases. It also produces proof storage directories and receipts under evidence/.
For a direct local run after setting the input file:
$env:APIFY_LOCAL_STORAGE_DIR = Join-Path (Get-Location) 'storage'C:/GritWork/earn/.venv/Scripts/python -m src
Dockerfile uses apify/actor-python:3.12. Docker/cloud builds and hosted monetization remain unverified in this local delivery. Verification receipts and publication risks are recorded in REPORT.md.