# UPC & EAN Barcode Lookup — Product Data by Barcode or Keyword (`yugenox/upc-ean-product-lookup`) Actor

Look up UPC, EAN, GTIN and ISBN barcodes in bulk: title, brand, model, category, images, size, weight, dimensions, recorded price range, merchants and the Amazon ASIN when known. Or search by keyword or brand to get products with their barcodes. No API key.

- **URL**: https://apify.com/yugenox/upc-ean-product-lookup.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 product founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## UPC & EAN Barcode Lookup: product data by barcode or keyword

Turn barcodes into product data, or keywords into barcodes. No API key, no signup, no per-day cap to plan around.

- **Barcode → product.** Paste UPC, EAN, GTIN or ISBN codes and get back the title, brand, model, category, images, description, size, color, weight, dimensions, recorded price range, merchants that listed it and, when known, the Amazon ASIN.
- **Keyword / brand → products with barcodes.** Search "lego star wars" or "stanley quencher 40oz" and get a product list with UPC, EAN and ASIN for each, up to 1,000 per keyword and beyond (see FAQ).
- **Bulk-friendly.** Thousands of barcodes per run. Check digits are verified before anything is looked up, spreadsheet debris is cleaned (a lost leading zero, a `'` or `="…"` text marker, a `.0` suffix, a "UPC:" label, full-width digits), UPC-E and ISBN-10 are converted automatically, and invalid or unknown barcodes come back as clearly-labelled rows **that are never charged**.
- **Second source for groceries and cosmetics.** Barcodes the main product database does not know are checked in Open Food Facts, Open Beauty Facts, Open Pet Food Facts and Open Products Facts.

### What you can use it for

- **Catalog and inventory enrichment**: fill in titles, brands, images, categories and weights for a spreadsheet of barcodes.
- **Amazon and marketplace sellers**: identify products from their barcodes, find the ASIN when one is on record, and build sourcing lists by brand or keyword with their UPCs.
- **Retail arbitrage and wholesale lists**: turn a supplier's barcode list into readable product data in minutes.
- **Data cleaning**: validate check digits, normalise every code to EAN-13 / UPC-A / GTIN-14, and flag bad codes.
- **Scanning apps and POS systems**: resolve scanned codes to product names and images.

### Input

| Field | What it does |
|---|---|
| **Barcodes** | UPC-A, UPC-E, EAN-13, EAN-8, GTIN-14, ISBN-10, ISBN-13. One per line, or paste a whole column. |
| **Search by keyword** | Product name, brand + product, or model. Each keyword runs its own search. |
| Max results per keyword | Default 100. |
| Brand filter / Category filter | Narrow keyword searches, e.g. brand "LEGO", category "Toys". |
| Keyword matching | *Best match* (default) or *Broad* (any word). |
| Go past 1,000 results per keyword | Re-runs large keywords per brand to collect more (default on). |
| Try Open Food Facts for barcodes not found | Default on. |
| Look harder for Amazon ASINs | Checks each product's page when its record has no ASIN (slower). |
| Include merchant offers | Adds the per-store offer list to every row (default off; the price range and merchant names are always included). |
| Output rows for barcodes not found | Default on, so your output lines up with your input. These rows are free. |
| Max products | Stop after N products. |

Example:

```json
{
  "barcodes": ["885909950805", "4002293401102", "0 45496 59042 0", "0735211299"],
  "searchQueries": ["lego star wars"],
  "maxResultsPerQuery": 50
}
```

### Output

One row per barcode you entered, plus one row per product found by keyword search. Every row has the same columns, so exports to CSV and Excel line up. A real row:

```json
{
  "inputBarcode": "0045496590420",
  "barcodeType": "EAN-13",
  "found": true,
  "source": "upcitemdb",
  "title": "The Legend of Zelda: Breath of the Wild - Nintendo Switch",
  "brand": "Nintendo",
  "model": "NINTENDO",
  "color": "Black",
  "weight": "1 lb",
  "category": "Electronics > Video Game Consoles",
  "categoryPath": ["Electronics", "Video Game Consoles"],
  "description": "Forget everything you know about The Legend of Zelda games. Step into a world of discovery…",
  "image": "https://cms.gameflycdn.com/proxy/gf/boxart/640w/5012923.jpg",
  "images": ["https://cms.gameflycdn.com/proxy/gf/boxart/640w/5012923.jpg", "…"],
  "ean": "0045496590420",
  "upc": "045496590420",
  "gtin14": "00045496590420",
  "asin": "B01MS6MO77",
  "amazonUrl": "https://www.amazon.com/dp/B01MS6MO77",
  "lowestRecordedPrice": 3.99,
  "highestRecordedPrice": 4979,
  "currency": "CAD",
  "offerCount": 30,
  "merchants": ["Newegg Canada", "GameFly", "BrandsMart USA", "Sam's Club", "Kohl's"],
  "lastPriceUpdate": "2026-09-24T02:29:58.000Z",
  "ebayListingId": "394709843846",
  "productUrl": "https://www.upcitemdb.com/upc/0045496590420",
  "scrapedAt": "2026-09-24T04:30:37.499Z"
}
```

A grocery item found through the second source:

```json
{ "inputBarcode": "4335619291959", "found": true, "source": "openfoodfacts", "title": "Maple Pizzelle Italian Style Waffle Cookies", "brand": "Lidl", "size": "6 oz", "productUrl": "https://world.openfoodfacts.org/product/4335619291959" }
```

A barcode with a typo (free):

```json
{ "inputBarcode": "0885909950806", "found": false, "notFoundReason": "invalid_checksum" }
```

Other fields: `size`, `dimension`, `isbn10`, `asinSource` (`database`, `web` or `isbn10`), `alternativeTitles`, `countryOfRegistration`, `quantity` and `ingredients` (Open Food Facts rows), `searchQuery` (keyword rows), and `offers` when enabled (merchant, title, price, list price, currency, shipping, condition, availability, `updatedAt`).

### Coverage: what to expect

- **Match rate** depends on what you look up. Established retail products (electronics, toys, kitchen, tools, books, media) match very often. Very new products and store-brand groceries match less often in the main database, which is why the Open Food Facts fallback is on by default. In our tests a mixed list of 89 real barcodes returned 82 products.
- **Amazon ASIN** is included only when it is on record. Expect it on roughly **a third of products overall**, more for older and popular items, and fewer for products from the last year or two. Books always get their ASIN (the ISBN-10).
- **Prices are recorded prices, not live prices.** `lowestRecordedPrice` / `highestRecordedPrice` are the range seen across stores over the product's history. `lastPriceUpdate` tells you how recent the newest price is. Popular products are refreshed often; long-tail items can be years old.

### FAQ

**Which barcodes are supported?**
UPC-A (12 digits), UPC-E (8 digits, converted to UPC-A), EAN-13, EAN-8, GTIN-14 (case codes resolve to the item inside) and ISBN-10/13. An Amazon ASIN is not a barcode and is rejected with a clear message.

**Do I pay for barcodes that are not found?**
No. Only rows with `found: true` are charged. Invalid, unknown and failed barcodes are returned with `found: false` and a `notFoundReason`, at no cost.

**What if my list has the same barcode twice?**
Each distinct product is looked up and charged once. "0 45496 59042 0", "045496590420" and "0045496590420" count as the same barcode.

**Why do some keywords return nothing?**
A single very broad word (e.g. "iphone") often returns no matches. Use two or more words, such as brand + product ("apple iphone 13") or a model number.

**Can I get more than 1,000 products for one keyword?**
Yes. A single search lists up to 1,000 products. When you ask for more, the actor re-runs the keyword once per brand it found and merges the results without duplicates.

**How fast is it?**
Around 200 barcodes plus two keyword searches of 60 products each finished in about 30 seconds in our tests. Keyword search returns about 5 products per request, so very large searches take longer than barcode lookups.

**Where does the data come from?**
Public product databases: UPCitemdb for the main records, and the Open Food Facts family (Open Food Facts, Open Beauty Facts, Open Pet Food Facts, Open Products Facts) for the fallback. Open Food Facts data is available under the Open Database License (ODbL). The `source` field on every row tells you which one it came from.

**Can I export to Excel or Google Sheets?**
Yes. Use the dataset export (CSV, Excel, JSON) or the Apify integrations.

**Is it legal to scrape UPCitemdb?**
This Actor only collects publicly available data: product records (barcodes, titles, brands, descriptions, image links, recorded prices and store names) that anyone can see on UPCitemdb and Open Food Facts without an account. Collecting publicly available data is generally legal, but you're responsible for how you use it. You must follow privacy laws such as GDPR, PIPEDA and CCPA, as well as UPCitemdb's and Open Food Facts' terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. Everything comes from product data UPCitemdb and Open Food Facts show to any visitor without logging in. It never uses a login, never touches private or restricted accounts, and never reaches password-protected areas.

# Actor input Schema

## `barcodes` (type: `array`):

UPC-A (12 digits), UPC-E (8), EAN-13, EAN-8, GTIN-14 or ISBN-10/13. One per line; you can also paste a whole column (commas, semicolons and line breaks all work). Spaces and dashes inside a code are ignored, and a UPC that lost its leading zero in Excel is fixed automatically. Check digits are verified before lookup, and invalid codes are returned as found=false at no charge.

## `searchQueries` (type: `array`):

Find products (with their UPC/EAN) by name, brand or model — e.g. "lego star wars", "stanley quencher 40oz". Each keyword runs its own search. Use two or more words: a single broad word often returns nothing.

## `maxResultsPerQuery` (type: `integer`):

How many products to return for each keyword. A single search lists up to 1,000 products; above that the keyword is re-run per brand automatically (see below).

## `searchBrand` (type: `string`):

Only return products of this brand, e.g. "LEGO". Applies to every keyword.

## `searchCategory` (type: `string`):

Only return products whose category contains this text, e.g. "Kitchen" or "Toys".

## `matchMode` (type: `string`):

Best match: products matching your keywords as a whole (recommended). Broad: products matching any of the words — many more, less precise results.

## `splitLargeSearches` (type: `boolean`):

When a keyword has more than 1,000 matches and you asked for more, re-run it once per brand found to collect more products (duplicates removed).

## `enrichNotFound` (type: `boolean`):

Barcodes the main product database does not know are looked up in Open Food Facts, Open Beauty Facts, Open Pet Food Facts and Open Products Facts (strong for groceries, cosmetics and household goods). The source field says where each row came from.

## `fillMissingAsin` (type: `boolean`):

When a product has no ASIN in the main record, also check its product page for one. Finds a few more ASINs at the cost of one extra request per product (slower). Books always get their ISBN-10, which is their ASIN.

## `includeOffers` (type: `boolean`):

Add the list of recorded store offers (merchant, price, condition, last update) to each product. Off by default to keep rows small — the price range, merchant names and last price update are always included.

## `includeNotFound` (type: `boolean`):

Keep a found=false row (with the reason) for every barcode that is invalid or unknown, so your output lines up with your input. These rows are free.

## `maxItems` (type: `integer`):

Stop after this many products have been found. Leave empty for no limit.

## `maxConcurrency` (type: `integer`):

Requests in flight at once. The default is fine for most runs.

## `proxyConfiguration` (type: `object`):

Apify Proxy is required. Datacenter proxy (the default) is fastest and cheapest.

## `residentialOverflow` (type: `boolean`):

Keeps big runs fast: when all datacenter IPs are busy, requests also go out through residential IPs. Turn off to use only the proxy above (large runs will be slower).

## Actor input object example

```json
{
  "barcodes": [
    "885909950805",
    "4002293401102"
  ],
  "searchQueries": [
    "lego star wars"
  ],
  "maxResultsPerQuery": 20,
  "matchMode": "all",
  "splitLargeSearches": true,
  "enrichNotFound": true,
  "fillMissingAsin": false,
  "includeOffers": false,
  "includeNotFound": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialOverflow": true
}
```

# Actor output Schema

## `results` (type: `string`):

All products and not-found barcodes.

## `run` (type: `string`):

Status and statistics for this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "barcodes": [
        "885909950805",
        "4002293401102"
    ],
    "searchQueries": [
        "lego star wars"
    ],
    "maxResultsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/upc-ean-product-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "barcodes": [
        "885909950805",
        "4002293401102",
    ],
    "searchQueries": ["lego star wars"],
    "maxResultsPerQuery": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/upc-ean-product-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "barcodes": [
    "885909950805",
    "4002293401102"
  ],
  "searchQueries": [
    "lego star wars"
  ],
  "maxResultsPerQuery": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/upc-ean-product-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/upc-ean-product-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gE6TVfv9sc0Qp8mEU/builds/d9afUtzraAkr1avYK/openapi.json
