Barcode check digit calculator for EAN-13, UPC-A and Code 128
A barcode check digit is the small arithmetic safeguard that helps scanners and catalog systems detect mistyped data.
Run — free
Enter the numeric payload, choose EAN-13, UPC-A, or Code 128 Mod-103, and this calculator returns the value required by that symbology. It checks the payload length before calculating, keeps leading zeroes intact, and performs the work deterministically without a registry lookup. Use it while preparing product records, label data, test fixtures, or automated import pipelines.
Provide the payload, not an already completed barcode
Start with the digits that carry the data and leave off the check digit you want to calculate. For EAN-13, enter exactly twelve data digits; the result supplies the thirteenth digit and also returns the completed thirteen-digit barcode. For UPC-A, enter exactly eleven data digits and the result supplies the twelfth. Keep the value as text when calling the API so a leading zero remains part of the barcode. The calculator rejects spaces, punctuation, signs, decimal points, and any other non-digit character because silently cleaning an identifier can hide a transcription error. It also rejects a payload whose digit count does not fit the selected symbology. This explicit contract is useful when a spreadsheet column or product feed contains several identifier formats: select the intended standard instead of guessing from the input. The calculation establishes mathematical consistency only. It does not allocate a company prefix, confirm ownership, or prove that a number is registered to a real product.
How EAN-13 and UPC-A check digits are calculated
EAN-13 and UPC-A use the same modulo-ten weighting pattern. Working from the rightmost data digit toward the left, the calculator multiplies alternating positions by three and one, adds those products, and chooses the digit that raises the total to the next multiple of ten. If the sum is already divisible by ten, the check digit is zero. The different names still matter because their required lengths differ: EAN-13 has twelve payload digits before its check digit, while UPC-A has eleven. A correct check digit catches every single-digit substitution and many common transpositions, which makes it valuable for data entry and scanning, but it is not a cryptographic signature. Two or more coordinated changes can occasionally preserve the same result. Treat it as a fast structural safeguard, then apply any separate business rules your catalog requires. Because the operation uses only fixed integer arithmetic, the same input and selected symbology always produce the same output in the browser and through the API.
How numeric Code 128 Mod-103 is handled
For Code 128 Mod-103, this capability uses Code Set C, the compact representation intended for numeric data in pairs. Enter an even number of digits from two through ninety-eight. Each two-digit pair becomes one Code 128 codeword with a value from zero through ninety-nine. The checksum begins with the Start C value of 105, then adds each data codeword multiplied by its one-based position. Taking that total modulo 103 yields the returned check value. That value may contain one, two, or three decimal characters in the JSON response, but it represents one Code 128 checksum codeword rather than printable digits appended to the original text. A barcode renderer must encode that checksum codeword and then add the stop pattern. This calculator intentionally does not choose among Code Sets A, B, and C or optimize shifts between them; accepting digits only makes the encoding assumption explicit and reproducible. Use another encoder when the payload includes letters, punctuation, or an odd trailing digit requiring a code-set change.
What you can do with it
Prepare retail product labels
Calculate the final EAN-13 or UPC-A digit before sending approved product numbers to label-design or barcode-rendering software.
Validate an import pipeline
Generate expected check digits for product-feed tests and reject records whose payload length does not match the declared barcode standard.
Build numeric Code 128 fixtures
Obtain the Mod-103 checksum codeword for Code Set C payloads when testing scanners, encoders, warehouse labels, or integration code.
FAQ
Should I include the existing check digit in the number?
No. Enter twelve data digits for EAN-13, eleven for UPC-A, or the even-length numeric Code 128 payload.
Why must the barcode number be sent as text?
Text preserves leading zeroes exactly. A numeric JSON value can lose them and change the barcode's required length.
Does a correct result prove that a product is registered?
No. The result proves only that the check value follows the selected arithmetic rule; it does not query a product or company registry.
Why does Code 128 require an even number of digits?
This capability uses Code Set C, which encodes numeric data as two-digit codewords. Mixed or odd-length content needs a full Code 128 encoder.
What does the API request cost?
Each API request costs $0.002. The same deterministic calculation can also run free in the browser.
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/web/barcode-check-digit \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"400638133393","symbology":"ean13"}'const res = await fetch("https://api.kit.forhosting.com/web/barcode-check-digit", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"number": "400638133393",
"symbology": "ean13"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/barcode-check-digit",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"number": "400638133393",
"symbology": "ean13"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/barcode-check-digit", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"number":"400638133393","symbology":"ean13"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"number":"400638133393","symbology":"ean13"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/barcode-check-digit", 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",
"symbology": "ean13"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.barcode_check_digit",
"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.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
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. |