EAN-13 check digit calculator
Enter the twelve product digits and get the thirteenth: 400638133393 gets check digit 1 and prints as 4006381333931. Paste a full EAN-13 instead to catch a mistyped barcode before labels go to print or a supplier file is imported. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Number
- 400638133393
- Calculation mode
- Compute
- Input
- 400638133393
- Check digit
- 1
- Ean13
- 4006381333931
Retail products, packaging lines, and catalogue systems almost always identify items with a thirteen-digit EAN-13 (also called GTIN-13) barcode. Twelve of those digits carry the GS1 company prefix and the item reference; the thirteenth is a check digit derived from a fixed alternating-weight formula so that a single mistype or transposition is far more likely to fail than to look like a different valid product. This capability computes that check digit from a twelve-digit product number, or validates a complete thirteen-digit barcode and reports whether the stored trailing digit matches the recomputed value.
How the EAN-13 check digit is calculated
The GS1 specification for EAN-13 (identical in structure to GTIN-13) defines a deterministic check digit over the first twelve digits. Number those data positions from the left starting at index zero: each digit is multiplied by weight one when the index is even, and by weight three when the index is odd, then the twelve weighted values are summed. The check digit is ten minus that sum modulo ten, taken modulo ten again so that a sum already divisible by ten yields check digit zero.
Appending that single digit produces the full thirteen-digit code printed under the bars and encoded in the symbol. Validation is the inverse: recompute the expected digit from the first twelve characters and compare it to the thirteenth.
Where EAN-13 check digits fit real product workflows
Brand owners and private-label teams receive a GS1 company prefix and assign item references; before artwork goes to print they must append the correct check digit so retail scanners accept the symbol on first scan. Warehouse and 3PL systems import supplier CSVs of thirteen-digit codes and should reject rows whose check digit no longer matches, which catches both human edits and off-by-one bugs in upstream generators. E-commerce catalogue tools that let merchants type an EAN can validate on blur and block listing until valid is true, reducing failed marketplace submissions.
Print shops that compose shelf labels from twelve-digit product numbers call compute mode once per SKU and place ean13 under the barcode graphic. Do not treat a passing check digit as proof of GS1 allocation or brand ownership — it only proves the thirteen-digit string is arithmetically well formed under the EAN-13 rule, the same honesty bar you apply to any retail checksum.
What you can do with it
Complete a twelve-digit product number for print
Take the GS1 prefix plus item reference (twelve digits), call compute mode, and print ean13 under the bars so the label carries a scanner-valid EAN-13.
Audit supplier GTIN columns
Batch-validate every EAN-13 in a partner CSV or ERP export and quarantine rows whose check digit no longer matches the recomputed expected value.
FAQ
What is an EAN-13 check digit?
It is the thirteenth digit of a retail barcode, computed from the first twelve digits with GS1 alternating weights of 1 and 3 so single-digit typos are far more likely to fail validation than to look like another product.
Is the EAN-13 check digit tool free?
The browser tool is free and runs locally.
How is the EAN-13 check digit calculated?
Multiply the twelve digits alternately by 1 and 3, starting with 1 on the first digit, and add the results. The check digit is whatever brings that sum up to the next multiple of ten, or 0 if it is already one.
How do I check a full 13-digit barcode?
Choose the validate option and enter all thirteen digits. The tool recomputes the digit from the first twelve, tells you whether the last one matches and shows the expected digit, so you can fix the code before it reaches a label or a catalogue.
Does a valid EAN-13 prove that the product is registered?
No. A matching check digit only proves that the thirteen digits are well formed under the EAN-13 rule. It says nothing about whether the number was allocated by GS1 or who owns the brand.
Related tools
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, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/ean-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"400638133393"}'const res = await fetch("https://api.kit.forhosting.com/enc/ean-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"number": "400638133393"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/ean-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"number": "400638133393"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/ean-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"number":"400638133393"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"number":"400638133393"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/ean-check", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"number": "400638133393"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.ean_check",
"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. |
Technical notes
Non-numeric characters and wrong lengths are rejected with a clear invalid_input error instead of silently stripping garbage. Run it free in the browser or call the KIT API at the published price; both paths use the same pure arithmetic with no network round-trip and no stored barcodes.
How the EAN-13 check digit is calculated
The same rule underpins related retail identifiers such as UPC-A when zero-padded to thirteen digits, but this tool focuses strictly on the twelve-plus-one EAN-13 layout so search intent and API contracts stay clear. Because the algorithm is pure integer arithmetic with fixed weights, the same product number always produces the same check digit on every platform — browser, Worker, or offline test harness — which is why the capability ships as a tier-A parse engine rather than a model call.
How to compute a check digit or validate a full barcode
Send a number field that contains only characters zero through nine. Mode validate expects exactly thirteen digits. Empty strings, missing number, invalid mode values, and wrong lengths (for example eleven or fourteen digits) fail before any weighted sum runs and are not billed. Spaces, hyphens, letters, and decimal points are rejected as non-numeric input with invalid_input so a form never accepts a silently cleaned value. Mode compute is the default: provide exactly twelve product digits; the engine returns check_digit as a one-character string, ean13 as the twelve digits plus that check digit, and length thirteen. The response reports valid true when the trailing digit matches the recomputed expected_check_digit, and always includes payload (the first twelve digits), check_digit as submitted, expected_check_digit, and the canonical ean13 built from payload plus expected digit. That shape makes it easy to show “you typed X, expected Y” in a packaging UI without a second request. Because the path is pure parse with no clock, random source, or network, the same input always yields the same JSON on the free browser tool and on the API. At $0.002 per successful request you can protect bulk catalogue imports, label printers, and partner file audits without negotiating a custom tier. Prefer compute when you mint or complete a new product code; prefer validate when you receive a full barcode from a scanner, a CSV, or a supplier feed and need a boolean gate before storing the SKU.
Where EAN-13 check digits fit real product workflows
Integration tests and data-quality jobs recompute expected_check_digit for every GTIN column in an export and quarantine mismatches before they reach the point of sale.
Integration use cases
Validate scanned or typed barcodes at entry
When a handheld scanner or form submits thirteen digits, call validate mode and block stock or catalogue updates when valid is false, showing expected_check_digit to fix a mistype.
Technical questions
How do I compute an EAN-13 check digit with this API?
POST with number set to exactly twelve digits and mode compute (or omit mode). The response includes check_digit and ean13 (the full thirteen-digit code).
How do I validate a full thirteen-digit barcode?
POST with the thirteen-digit string and mode validate. The response includes valid, check_digit, expected_check_digit, payload, and the canonical ean13.
What happens with letters, spaces, hyphens, or wrong lengths?
Non-numeric input and lengths other than twelve (compute) or thirteen (validate) are rejected with invalid_input. Failed validation tasks are not billed.