Validate a barcode
A barcode with a single mistyped digit still looks like a barcode, right up until a scanner rejects it at the register or a marketplace bounces the listing. This ean upc validation api recalculates the check digit for EAN-13, EAN-8, UPC-A, UPC-E and ISBN codes and confirms whether the number is internally consistent, in a single request.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Why check digits exist at all
Every EAN, UPC and ISBN ends in a digit that isn't part of the product's identity at all, it's arithmetic. The check digit is calculated from the preceding numbers using a fixed weighting formula, so if even one digit was transposed during data entry, a spreadsheet import, or an OCR scan of a printed label, the math no longer adds up and the code is provably wrong. That's the entire point: a scanner can catch a typo without needing to look anything up.
What POST /verify/barcode does
You send the barcode string and, optionally, the expected symbology. The task strips formatting, confirms the length matches a known standard, recalculates the check digit using the correct algorithm for that format, and compares it to the one supplied. The response tells you whether the code is valid and which symbology it matched, so a code that happens to pass as both EAN-13 and a malformed UPC-A doesn't leave you guessing.
A format with more history than it looks
The UPC was adopted commercially in the United States in 1974, first scanned on a pack of chewing gum in an Ohio supermarket. EAN followed shortly after as the international extension, adding a country-prefix digit so the same infrastructure could work worldwide. ISBN, unrelated in origin but similar in structure, dates to a 1960s numbering scheme for booksellers and was later folded into the same check-digit logic used by EAN-13. Three different industries, one shared idea: numbers that can catch their own mistakes.
Where it belongs in a real workflow
Run it when a supplier feed lands with thousands of new SKUs and you need to know which barcodes are structurally sound before they ever reach a catalog or a point-of-sale system. Run it before submitting listings to a marketplace that rejects malformed codes outright. Because the task is asynchronous, you submit and move on, then collect results through a signed webhook or a signed link that stays valid for 24 hours, no polling loop required.
What it won't do
It confirms mathematical validity, not that a code is registered to a real product or that it isn't a duplicate in your own catalog. Those are separate problems that need separate data. What it gives you is a fast, honest first filter that removes the codes you already know are broken, before they cost you a rejected shipment.
What you can do with it
Supplier feed screening
Check every barcode in a new product feed before import, so structurally invalid EAN or UPC codes never reach the catalog.
Marketplace listing prep
Validate ISBN or EAN codes ahead of submission to a marketplace that rejects listings with malformed check digits.
Point-of-sale data entry checks
Catch a mistyped digit from a manually entered barcode before it's saved to inventory and causes a scan mismatch later.
Legacy catalog cleanup
Sweep an old product database in bulk to flag barcodes whose check digit no longer computes correctly.
FAQ
Which barcode formats does this ean upc validation api support?
EAN-13, EAN-8, UPC-A, UPC-E and ISBN, each verified with the check-digit algorithm specific to that format.
Does it confirm the barcode is a real, registered product?
No, it confirms the check digit is mathematically correct for the given symbology. Registry lookups are a different kind of data this endpoint doesn't claim to hold.
Can I validate ISBNs with this same endpoint?
Yes, ISBN-10 and ISBN-13 are both supported alongside EAN and UPC formats.
Is there a free trial?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
What's the cost per check?
$0.002 per request, charged only when the task completes successfully.
How do I retrieve results for a batch of barcodes?
Each request to POST /verify/barcode returns a task_id right away, and results arrive via signed webhook or a signed link valid for 24 hours.
What happens if the task fails?
It retries automatically up to three times; if it still can't complete, you get a clear error and no charge.
Can it detect a duplicate barcode already in my catalog?
No, that requires comparing against your own data, which this endpoint doesn't have access to. It only validates the code's internal consistency.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/verify/barcode \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"items":["valor-1","valor-2"]}'const res = await fetch("https://api.kit.forhosting.com/verify/barcode", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"items": [
"valor-1",
"valor-2"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/verify/barcode",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"items": [
"valor-1",
"valor-2"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/verify/barcode", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"items":["valor-1","valor-2"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"items":["valor-1","valor-2"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/verify/barcode", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"items": [
"valor-1",
"valor-2"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "verify.barcode",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |