Barcode Validator (EAN, UPC, GTIN)
Pricing
from $5.00 / 1,000 valid barcode checkeds
Barcode Validator (EAN, UPC, GTIN)
Validates and normalises EAN, UPC and GTIN barcodes: check digit, format, GTIN-14 normalisation, UPC-E expansion and GS1 prefix allocation. No external lookups, runs offline and deterministically.
Pricing
from $5.00 / 1,000 valid barcode checkeds
Rating
0.0
(0)
Developer
Nico Poland
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Validates and normalises EAN, UPC and GTIN barcodes: check digit, format, GTIN-14 normalisation, UPC-E expansion and GS1 prefix allocation. No external lookups; runs offline and deterministically.
What it does
Send a list of barcodes, get one row back for each, in the same order, so the output joins straight onto your input. For every barcode it tells you:
- whether the check digit is correct, and what it should have been;
- the format: GTIN-8, UPC-E, GTIN-12 (UPC-A), GTIN-13 (EAN-13) or GTIN-14;
- the GTIN-14 form, zero-padded, the shape GS1 recommends storing, and
the only reliable way to match
12345670against00000012345670; - the UPC-A expansion for UPC-E codes, which cannot be recovered by padding because the compression depends on the last digit's value;
- the GS1 prefix and what it is allocated to, including ISBN, ISSN, coupon and restricted-circulation ranges.
Everything is computed locally from the published GS1 specification. There is no API behind this, nothing to rate-limit, and the same input always gives the same output, so it is safe to call from an agent or a pipeline at any volume.
What it does not do. It does not look products up. A valid barcode means the number is well-formed and its check digit is correct; it does not mean the code has been issued to anyone, or that a product exists. Product lookup requires a licensed commercial database, which this Actor deliberately does not use.
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
barcodes | array of strings | yes | n/a | Up to 50,000 per run. Spaces and hyphens are ignored. |
failOnEmpty | boolean | no | false | Operator health check; leave off. |
{"barcodes": ["5449000000996", "036000291452", "9780306406157", "1234567890123"]}
Output
One row per input, in order. A real row from a real run:
{"input": "5449000000996","valid": true,"format": "GTIN-13","gtin": "5449000000996","gtin14": "05449000000996","check_digit": 6,"expected_check_digit": 6,"gs1_prefix": "544","prefix_allocation": "Belgium and Luxembourg","prefix_type": "gs1_member_organisation","is_restricted_circulation": false,"source": "GS1 General Specifications (computed locally)","source_url": "https://www.gs1.org/standards/barcodes","license": "Computed from the published GS1 specification; no third-party data","retrieved_at": "2026-09-06T12:00:00+00:00"}
And a rejection:
{"input": "5449000000997","valid": false,"check_digit": 7,"expected_check_digit": 6,"reason": "Check digit is 7; the GS1 modulo-10 algorithm gives 6 for these digits."}
| Field | Type | Description |
|---|---|---|
input | string | Your value, echoed back exactly. Present on every row, including empty ones, so nothing breaks the join. |
valid | boolean | Well-formed and check digit correct. |
format | string | GTIN-8, UPC-E, GTIN-12, GTIN-13 or GTIN-14. |
gtin14 | string | Zero-padded to 14. Use this to match across sources. |
expected_check_digit | integer | What GS1's algorithm computes. Differs from check_digit exactly when invalid. |
reason | string | Why it was rejected. Absent when valid. |
gs1_prefix | string | Prefix digits, read correctly for the detected format. |
prefix_allocation | string | Which GS1 Member Organisation issued the range, or its special purpose. |
prefix_type | string | gs1_member_organisation, restricted_circulation, isbn, issn, coupon, refund_receipt, reserved or demonstration. |
is_restricted_circulation | boolean | true for internal codes. These are not globally unique. Do not treat them as product identifiers. |
upc_a | string | 12-digit UPC-A form, for UPC-E codes. |
indicator_digit | string | First digit of a GTIN-14: 0 base item, 1–8 packaging level, 9 variable measure. |
also_valid_as | string | Set when an 8-digit code reads validly as both GTIN-8 and UPC-E, which is real ambiguity in the standard, surfaced rather than guessed at. |
A note on prefixes and countries
GS1 is explicit that prefixes do not identify a product's country of
origin. A company can license a prefix from the GS1 organisation of its
choice and manufacture anywhere. So prefix_allocation names the GS1
Member Organisation that issued the number, and the field is
deliberately not called country. Tools that label it that way are
telling you something false about supply chains.
Pricing
Pay per event. You are charged $0.005 per valid barcode, plus Apify's standard $0.00005 Actor start event.
Invalid barcodes are returned free. You should not pay to be told your own input was malformed.
Example: 1,000 barcodes of which 900 are valid = 900 × $0.005 + $0.00005 = $4.50.
Limits and refresh cadence
- No external source. Nothing to be down, nothing to rate-limit, no cache. Runs are deterministic: identical input, identical output.
- Throughput: up to 50,000 barcodes per run. 50,000 completes in about a minute and a half.
- Coverage: GTIN-8, UPC-E, GTIN-12 (UPC-A), GTIN-13 (EAN-13) and GTIN-14. SSCC-18 logistics labels and ISBN-10 are out of scope.
- Prefix table: GS1 reassigns and adds prefix ranges occasionally. Unassigned ranges are reported as such rather than guessed at.
- Validity is arithmetic, not existence. See What it does not do.
Attribution
Implements the check digit and prefix scheme published in the GS1 General Specifications. No third-party data is fetched, stored or redistributed, and no barcode you submit leaves the run.
Changelog
See the Changelog tab.
Issues
Report problems on the Issues tab. Please include the barcode and what you expected. Breakage is normally fixed within one working day.