Introduction

NutriGraphAPI
Reference

NutriGraphAPI is a REST API returning food intelligence across 6M+ UPC-indexed products. Every response contains two root objects: scraped_data (on-label manufacturer declarations) and analysed_data (AI-qualified intelligence layer). Always build against analysed_data for application logic.

Full payload on the free tier. The Developer plan returns the identical response as paid plans. Every attribute, every score, every flag — from call one. The only limit is volume: 1,000 calls/month.

Base URL: https://barcode-api-140543331861.asia-south1.run.app/api

Authentication: X-API-Key header — request your key

Format: JSON, UTF-8, always

Authentication

Authentication

All requests must include your API key in the X-API-Key header. Keys are issued per legal entity. To request a key, email support@nutrigraphapi.com.

Keep your key private. Do not embed it in client-side code, commit it to public repositories, or expose it in browser network requests. If compromised, contact us immediately for a replacement.
cURL
curl -i \ -H "X-API-Key: YOUR_API_KEY" \ "https://barcode-api-140543331861.asia-south1.run.app/api/lookup?barcode=039978009579"
Getting started

Quick-start

Your first call in four languages. All return the identical full payload.

Node.js

Node.js
const API_KEY = 'YOUR_API_KEY'; const barcode = '039978009579'; const res = await fetch( `https://barcode-api-140543331861.asia-south1.run.app/api/lookup?barcode=${barcode}`, { headers: { 'X-API-Key': API_KEY } } ); const { analysed_data } = await res.json(); // Access any attribute: const nova = analysed_data.additionalInfo.nova_group; const isVegan = analysed_data.additionalInfo.dietary_preference.Vegan; const gluten = analysed_data.npiFoodPackagesAllergensIntolerances.glutenQualified;

Python

Python
import requests API_KEY = 'YOUR_API_KEY' barcode = '039978009579' resp = requests.get( 'https://barcode-api-140543331861.asia-south1.run.app/api/lookup', params={'barcode': barcode}, headers={'X-API-Key': API_KEY} ) data = resp.json()['analysed_data'] nova = data['additionalInfo']['nova_group'] is_vegan = data['additionalInfo']['dietary_preference']['Vegan'] allergens = data['npiFoodPackagesAllergensIntolerances'] clean = data['cleanLabel'] # 30+ fields

Swift

Swift
let apiKey = "YOUR_API_KEY" let barcode = "039978009579" let url = URL(string: "https://barcode-api-140543331861.asia-south1.run.app/api/lookup?barcode=\(barcode)")! var request = URLRequest(url: url) request.setValue(apiKey, forHTTPHeaderField: "X-API-Key") let (data, _) = try await URLSession.shared.data(for: request) let product = try JSONDecoder().decode(NutriGraphProduct.self, from: data)
Endpoints

Product lookup

GET /api/lookup
Returns the full intelligence payload for a product identified by UPC-12 barcode. Both scraped_data and analysed_data are returned on every successful response.
Parameters
ParameterTypeRequiredDescription
barcodestringRequiredUPC-12 barcode of the product. Leading zeros must be preserved. Example: 039978009579
Example request
cURL
curl -i \ -H "X-API-Key: YOUR_API_KEY" \ "https://barcode-api-140543331861.asia-south1.run.app/api/lookup?barcode=039978009579"
Example response (condensed)
JSON
{ "scraped_data": { /* raw on-label manufacturer data */ }, "analysed_data": { "generalData": { "upc12": "039978009579", "brandName": "Bob's Red Mill", "category": "Steel Cut Oats", "numberOfIngredients": 1 }, "additionalInfo": { "nova_group": "1", "nutriscore_grade": "B", "ecoscore": "B", "dietary_preference": { "Vegan": true, "Vegetarian": true, "KetoFriendly": false, "LowFodmap": false }, "religious_labels": { "Kosher": true, "Halal": false, "Jain": false, "Hindu": false }, "sustainability_labels": { "PlantBased": true, "Recycled": true } }, "npiFoodPackagesAllergensIntolerances": { "glutenLevelStated": "Gluten-free", "glutenQualified": "Yes (certified on pack)", "falcpaCommonAllergensStated": "No", "additionalInfo": { "traces": "May be processed in facility with tree nuts" } }, "cleanLabel": { "artificialColorsQualified": "No", "preservativesQualified": "No", "gmoPresenceQualified": "Non-GMO", "recognizableIngredientsQualified": "Yes" }, "claims": { "certifications": ["USDA Organic", "Non-GMO Project Verified", "Kosher"] }, "ingredients": [ { "name": "Organic Whole Grain Oats", "allergens": { "Gluten": false, "Peanuts": false }, "dietary_preference": { "Vegan": true }, "religious_labels": { "Kosher": true } } ] } }
Endpoints

Request a product

POST /api/request
Submit a UPC that returned 404 for onboarding. Products are typically added within 48 hours. Bulk UPC lists are available on Enterprise plans — contact support@nutrigraphapi.com.
Body fieldTypeRequiredDescription
barcodestringRequiredThe UPC-12 that returned 404
product_namestringOptionalHelps us onboard faster
brandstringOptionalBrand name
cURL
curl -X POST \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"barcode":"012345678901","product_name":"Example Product","brand":"Example Brand"}' \ "https://barcode-api-140543331861.asia-south1.run.app/api/request"
For brands

Submit your products

Brands can list their own products free of charge. You send what is printed on the pack; NutriGraphAPI verifies it and derives the Qualified allergen, dietary and clean-label fields itself. Upload on /submit (JSON or CSV), or read on for the format. Nothing is published automatically — every submission goes to a private review queue first.

Files: JSON Schema · example.json · template.csv · limits: 500 products and 5 MB per file.
Top-level shape
schema_version"1.0"— required
submitterobject— company, contact_name, email, attest_accuracy, attest_image_rights (required); role, website, partner_ref
products[]array— 1 to 500 products
Product fields
FieldTypeRequiredNotes
gtinstringRequired8, 12, 13 or 14 digits, sent as text so leading zeros survive. The check digit is verified.
name, brandstringRequiredAs on the pack.
ingredients_textstringRequiredVerbatim ingredient list, label order, up to 5,000 characters.
allergens_declaredobjectRecommendedcontains[] and may_contain[]. Values: milk, eggs, fish, crustacean_shellfish, tree_nuts, peanuts, wheat, soybeans, sesame, gluten, celery, mustard, lupin, molluscs, sulphites. Send [] for “none” — leaving it out means “unknown”.
nutrition_per_servingobjectRecommendedenergy_kcal, fat_g, saturated_fat_g, trans_fat_g, cholesterol_mg, sodium_mg, carbs_g, fiber_g, sugars_g, added_sugars_g, protein_g.
serving, net_weightobjectOptionalServing size/unit/servings per pack; net weight value + unit.
claimsobjectOptionalcertifications[] (free text), diet_labels[] (vegan, vegetarian, pescatarian, keto_friendly, low_fodmap, gluten_free, dairy_free, paleo, no_added_sugar), religious[] (kosher, halal, jain, hindu).
imagesobjectRecommendedfront, ingredients, nutrition — https URLs to photos you have the right to share. Products with label photos clear review faster.
manufacturer, category, variant, country_of_sale, product_url, launch_date—Optionalcountry_of_sale uses ISO codes (["US","CA"]); launch_date is YYYY-MM-DD.
What the checker catches

The submit page validates as you type, with the same rules we apply on review: invalid barcode check digits, duplicate barcodes in one file, impossible nutrition values (sugars above total carbohydrate, saturated fat above total fat), a “vegan” label alongside milk or egg, and allergens that appear in your ingredient text but not in your declaration. The last kind is a warning, not a rejection — a reviewer will look at it.

After you submit

You receive a receipt ID and a confirmation email. We review in batches, usually within 14 days: label photos against your data, duplicate and conflict checks against existing records, then our own allergen and clean-label analysis. You get a data-readiness report listing anything to fix. Resubmit a product with the same gtin to correct it. Questions: support@nutrigraphapi.com.

Response schema

Allergens

Path: analysed_data.npiFoodPackagesAllergensIntolerances

Always use Qualified fields for safety logic. The Stated field reflects what the manufacturer declared on-label. The Qualified field is our AI-verified conclusion. For allergen filtering in your application, always use Qualified.
eggStatedstring— Egg allergen as declared on label
eggQualifiedstring— AI-verified egg allergen status
dairyStated / dairyQualifiedstring pair
glutenLevelStatedstring— e.g. "Gluten-free", "Contains gluten"
glutenQualifiedstring— AI-verified gluten status
fishStated / fishQualifiedstring pair
caseinStated / caseinQualifiedstring pair— Casein tracked separately from dairy
falcpaCommonAllergensStatedstring— FDA Big-9 declaration
fdaRegulatedAllergensstring— FALCPA summary
additionalInfo.tracesstring— May-contain / cross-contamination statement
ingredients[].allergensobject— Per-ingredient allergen tree
Peanuts, Milk, Egg, Wheat, Soy, Fish, Shellfish, Sesame, TreeNutsboolean
Response schema

Clean label

Path: analysed_data.cleanLabel — 30+ fields, each with a Stated (on-label) and Qualified (AI-verified) variant.

artificialColorsStated / artificialColorsQualifiedstring
artificialFlavorsStated / artificialFlavorsQualifiedstring
artificialSweetenersStated / artificialSweetenersQualifiedstring
preservativesStated / preservativesQualifiedstring
gmoPresenceStated / gmoPresenceQualifiedstring— e.g. "Non-GMO Project Verified"
highFructoseCornSyrupStated / highFructoseCornSyrupQualifiedstring
naturalColorsStated / naturalColorsQualifiedstring
sugarAlcoholsStated / sugarAlcoholsQualifiedstring
hormonesStated / antibioticsStatedstring
madeInUsaStatedstring
countOfIngredientsQualifiedstring— e.g. "Low (1 main ingredient)"
recognizableIngredientsQualifiedstring— "Yes" / "No"
Response schema

Dietary & religious

Path: analysed_data.additionalInfo — available at both product level and nested inside each ingredients[] item.

dietary_preferenceobject
Veganboolean
Vegetarianboolean
KetoFriendlyboolean
LowFodmapboolean
Pescatarianboolean
NoRedMeatboolean
religious_labelsobject
Kosherboolean
Halalboolean
Jainboolean
Hinduboolean
Response schema

Nutrition

Path: analysed_data.nutritionalInformation — two sub-objects: stated (from manufacturer) and qualified (AI-backfilled and verified). Per 100g with daily values.

Backfill flag. When qualified.backfillNutrientsProcessed is true, values were AI-enriched rather than sourced directly from a label. Reliable, but surface this distinction in clinical contexts.
stated.macronutrients[]array— Energy, Fat, SatFat, Carbs, Sugars, Fiber, Protein, Sodium
stated.micronutrients[]array— Iron + declared micros
qualified.macronutrients[]array— AI-verified macros + kJ
qualified.micronutrients[]array— Iron, Potassium, VitD, Calcium, VitA, VitC
each nutrient.valuefloat— Per 100g
each nutrient.dailyValuefloat— % Daily Value
each nutrient.sourcestring— Data provenance
servingSize.servingSizefloat— In grams
servingSize.servesPerPackinteger
qualified.backfillNutrientsProcessedboolean
Response schema

Quality scores

Path: analysed_data.additionalInfo and analysed_data.food_safety_labels — six scores returned in every response.

nova_groupstring "1"–"4"— NOVA processing level. 1=unprocessed, 4=ultra-processed
nutriscore_gradestring A–E— Nutri-Score nutritional quality
ecoscorestring A–E— Environmental impact
food_safety_labels.Organicboolean
food_safety_labels.NoGMOboolean
food_safety_labels.Carcinogenicboolean— Known carcinogenic ingredient flag
food_safety_labels.ProductRecallsboolean— Active recall flag
average_customer_ratingfloat— Marketplace rating
Response schema

Sustainability

Path: analysed_data.additionalInfo.sustainability_labels — six flags at product and ingredient level.

PlantBasedboolean
Recycledboolean— Recycled / recyclable packaging
SustainablePackagingboolean
OrganicPositioningboolean
SocialResponsibilityboolean
AnimalWelfareboolean
claims.sustainability.packaging[]string array— On-pack packaging claims
claims.sustainability.environmentalClaims[]string array
Reference

Error codes

All error responses use the same JSON envelope:

JSON
{ "error": "PRODUCT_NOT_FOUND", "upc": "012345678901", "message": "Submit via POST /api/request", "request_id": "req_abc123xyz" }
CodeMeaningAction
200 OKSuccessful responseRead analysed_data
401 UnauthorizedMissing or invalid API keyCheck your X-API-Key header
404 Not FoundUPC not in databaseSubmit via POST /api/request — onboarded within 48h
429 Too Many RequestsRate limit exceededWait for quota reset (1st of month for monthly plans)
500 Server ErrorUnexpected server errorRetry with exponential backoff. Contact support if persistent.
Reference

Rate limits

PlanMonthly quotaOn 429
Developer (free)1,000 calls/monthReturns 429 until month resets
Professional100,000 callsOverage billed at plan rate
Enterprise1,000,000 callsOverage billed at plan rate

Quotas reset on the 1st of each calendar month for monthly plans, or on the annual anniversary for annual plans.

Reference

Caching

Manufacturers reformulate without notice, so treat the cache as a short performance window rather than a substitute for the source — a record that has gone stale carries exactly the risk the lookup was there to remove. Cache for up to 24 hours, keyed on UPC-12, to avoid redundant calls, then revalidate. Use the data_last_updated field to selectively invalidate.

Node.js — Redis cache pattern
const CACHE_TTL = 86400; // 24 hours in seconds async function getProduct(upc) { const cacheKey = `nutrigraph:${upc}`; const cached = await redis.get(cacheKey); if (cached) return JSON.parse(cached); const res = await fetch( `https://barcode-api-140543331861.asia-south1.run.app/api/lookup?barcode=${upc}`, { headers: { 'X-API-Key': API_KEY } } ); const data = await res.json(); await redis.setex(cacheKey, CACHE_TTL, JSON.stringify(data)); return data; }
Permitted under Terms. Caching API responses for performance is explicitly permitted. Section 3 of the Terms sets 24 hours as the ceiling rather than a suggestion: cached responses stay inside your application and are not retained, exported or accumulated beyond that window. Records change when manufacturers reformulate, so the limit protects your users as much as our data.
Reference

Attribution

On the Developer (free) and Professional plans, any app, page or document that displays NutriGraphAPI data must carry a visible credit that links back to us. Enterprise and Custom plans with white-label access can remove it.

HTML
<a href="https://nutrigraphapi.com" rel="noopener">Data by NutriGraphAPI</a>
Where to place it. Next to or beneath the data, or in the footer or about screen of an app, at a legible size. Section 6 of the Terms has the full wording.
Reference

Changelog

June 2026 — v1.0
Initial public release. 6M+ products. Full analysed_data layer. Per-ingredient allergen trees. 30+ clean label fields. NovaScore, EcoScore, Nutri-Score. Four religious compliance labels. Six sustainability flags.

Questions or issues? Email support@nutrigraphapi.com — we respond within 24 hours.