Introduction

NutriGraphAPI
Reference

NutriGraphAPI is a REST API returning food intelligence across 5M+ 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"
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 callsReturns 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

Product data changes infrequently. We recommend a 24-hour client-side cache keyed on UPC-12 to reduce redundant calls and improve performance. 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. The 24-hour window is our recommendation, not a hard limit. See Section 3 of the Terms for full details.
Reference

Changelog

June 2026 — v1.0
Initial public release. 5M+ 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.