Skip to main content

Check Digit Validator and Calculator API

REAL DATA

Validate or compute check digits for Luhn, GTIN/EAN/UPC, ISBN, ISSN, IMEI, ISIN, LEI, VIN, NPI, ABA and ISO 7064 — one cited algorithm per scheme.

Authoritative reference data or standards computation

Base URL
/api/check-digits
Capabilities
4 routes
Last updated
July 29, 2026
Data source
  • Published check-digit algorithms: GS1 General Specifications, ISO/IEC 7064, ISO/IEC 7812-1, ISO 2108, ISO 3297, ISO 6166, ISO 10957, ISO 17442, ISO 3779 with 49 CFR 565.15, 3GPP TS 23.003, ANSI X9 and CMS — each cited per scheme

GET /api/check-digits

One record per scheme with its algorithm, alphabet, length rules, applicability scope, error-detection limits and specification reference.

Live requestRuns against the public API
No key required
GET/api/check-digits

Request parameters

Case-insensitive filter: any substring of the scheme id or name, or the start of any word in the algorithm description (so 'luhn' also finds imei, npi and isin). No match returns an empty list plus a warning — never a substitute scheme.

Advanced response options6 options

Limit the number of returned records (1–100). Defaults to 20.

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Response format: json envelope, ndjson (one record per line) or csv.

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/check-digits"
const res = await fetch("https://randomapi.dev/api/check-digits");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/check-digits").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/check-digits"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 1
search string

Case-insensitive filter: any substring of the scheme id or name, or the start of any word in the algorithm description (so 'luhn' also finds imei, npi and isin). No match returns an empty list plus a warning — never a substitute scheme.

allowed: 1 – 40
example: search=isbn
Universal parameters Shared response and formatting options 6
count int

Limit the number of returned records (1–100). Defaults to 20.

default: 20
allowed: 1 – 100
example: count=3
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=scheme,name
exclude list

Return all fields except these (comma-separated).

example: exclude=meaning
format enum

Response format: json envelope, ndjson (one record per line) or csv.

default: json
allowed: json | ndjson | csv
example: format=csv
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 18
scheme string

Scheme id used by the scheme parameter.

example: gtin13

name string

Human name of the identifier scheme.

example: GTIN-13 (EAN-13)

algorithm string

The check-character algorithm in one sentence.

example: GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten

alphabet string

Characters allowed in the payload.

example: 0-9

lengths integer[]

Accepted total lengths including the check characters. Empty for variable-length schemes.

example: [13]

minLength integer

Smallest accepted total length — the only length rule for variable-length schemes.

example: 13

checkCharacters integer

Number of check characters: 1 for most schemes, 2 for MOD 97-10 and LEI.

example: 1

checkAlphabet string

Characters the check position may hold.

example: 0-9

checkPosition string

Where the check characters sit in the identifier.

example: last character

scope string

Where the scheme (and its check character) actually applies — regional limits are stated here.

example: Global GS1 key, printed as an EAN-13 symbol.

strictRules string nullable

What strict=true adds on /validate, or null when the alphabet, length and check character are the whole format.

example: null

detectsAllSingleCharacterErrors boolean

Whether every single-character substitution changes the check character.

example: true

undetectedSubstitutions string nullable

Which single-character changes slip through, or null when none do.

example: null

detectsAllAdjacentTranspositions boolean

Whether swapping any two adjacent characters changes the check character.

example: false

undetectedTranspositions string nullable

Which adjacent swaps slip through, or null when none do.

example: Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.

specification string

The published specification this implementation follows.

example: GS1 General Specifications — check-digit calculation

specificationUrl string nullable

Public page for the specification, or null when only a paywalled standard exists.

example: https://www.gs1.org/standards/barcodes/ean-upc

meaning string

What a valid check character does and does not prove for this scheme.

example: A correct check digit means the digits are internally consistent. It does not mean the GTIN has been allocated to a company or assigned to a product — this endpoint queries no GS1 registry and holds no product catalogue.

Documented examples

Build-generated requests and complete responses
3
Every supported scheme
GET /api/check-digits
{
  "data": [
    {
      "scheme": "luhn",
      "name": "Luhn (generic mod-10)",
      "algorithm": "Luhn modulo-10: double every second digit from the right, add the digits of any result above nine, subtract the total from the next multiple of ten",
      "alphabet": "0-9",
      "lengths": [],
      "minLength": 2,
      "checkCharacters": 1,
      "checkAlphabet": "0-9",
      "checkPosition": "last character",
      "scope": "Global. The generic algorithm behind payment card numbers, IMEIs, NPIs and the final step of an ISIN.",
      "strictRules": null,
      "detectsAllSingleCharacterErrors": true,
      "undetectedSubstitutions": null,
      "detectsAllAdjacentTranspositions": false,
      "undetectedTranspositions": "Swapping an adjacent 0 and 9 is undetected, because both digits map to themselves when doubled. Every other adjacent transposition changes the check digit.",
      "specification": "ISO/IEC 7812-1, Annex B",
      "specificationUrl": "https://www.iso.org/standard/70484.html",
      "meaning": "A correct Luhn digit means the digit string is internally consistent. On its own it says nothing about what the number identifies, who issued it or whether it was ever allocated."
    },
    {
      "scheme": "gtin8",
      "name": "GTIN-8 (EAN-8)",
      "algorithm": "GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",
      "alphabet": "0-9",
      "lengths": [
        8
      ],
      "minLength": 8,
      "checkCharacters": 1,
      "checkAlphabet": "0-9",
      "checkPosition": "last character",
      "scope": "Global GS1 key for very small packaging.",
      "strictRules": null,
      "detectsAllSingleCharacterErrors": true,
      "undetectedSubstitutions": null,
      "detectsAllAdjacentTranspositions": false,
      "undetectedTranspositions": "Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Only the Luhn-based schemes
GET /api/check-digits?search=luhn
{
  "data": [
    {
      "scheme": "luhn",
      "name": "Luhn (generic mod-10)",
      "algorithm": "Luhn modulo-10: double every second digit from the right, add the digits of any result above nine, subtract the total from the next multiple of ten",
      "alphabet": "0-9",
      "lengths": [],
      "minLength": 2,
      "checkCharacters": 1,
      "checkAlphabet": "0-9",
      "checkPosition": "last character",
      "scope": "Global. The generic algorithm behind payment card numbers, IMEIs, NPIs and the final step of an ISIN.",
      "strictRules": null,
      "detectsAllSingleCharacterErrors": true,
      "undetectedSubstitutions": null,
      "detectsAllAdjacentTranspositions": false,
      "undetectedTranspositions": "Swapping an adjacent 0 and 9 is undetected, because both digits map to themselves when doubled. Every other adjacent transposition changes the check digit.",
      "specification": "ISO/IEC 7812-1, Annex B",
      "specificationUrl": "https://www.iso.org/standard/70484.html",
      "meaning": "A correct Luhn digit means the digit string is internally consistent. On its own it says nothing about what the number identifies, who issued it or whether it was ever allocated."
    },
    {
      "scheme": "imei",
      "name": "IMEI",
      "algorithm": "Luhn modulo-10 over the fourteen TAC and serial digits",
      "alphabet": "0-9",
      "lengths": [
        15
      ],
      "minLength": 15,
      "checkCharacters": 1,
      "checkAlphabet": "0-9",
      "checkPosition": "last character",
      "scope": "Global, for GSM/UMTS/LTE/NR mobile equipment.",
      "strictRules": null,
      "detectsAllSingleCharacterErrors": true,
      "undetectedSubstitutions": null,
      "detectsAllAdjacentTranspositions": false,
      "undetectedTranspositions": "Swapping an adjacent 0 and 9 is undetected, because both digits map to themselves when doubled. Every other adjacent transposition changes the check digit.",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
The four GTIN lengths as CSV
GET /api/check-digits?search=gtin&format=csv
scheme,name,algorithm,alphabet,lengths,minLength,checkCharacters,checkAlphabet,checkPosition,scope,strictRules,detectsAllSingleCharacterErrors,undetectedSubstitutions,detectsAllAdjacentTranspositions,undetectedTranspositions,specification,specificationUrl,meaning
gtin8,GTIN-8 (EAN-8),"GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",0-9,[8],8,1,0-9,last character,Global GS1 key for very small packaging.,,true,,false,"Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.",GS1 General Specifications — check-digit calculation,https://www.gs1.org/standards/barcodes/ean-upc,A correct check digit means the digits are internally consistent. It does not mean the GTIN has been allocated to a company or assigned to a product — this endpoint queries no GS1 registry and holds no product catalogue.
gtin12,GTIN-12 (UPC-A),"GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",0-9,[12],12,1,0-9,last character,"Global GS1 key, printed as a UPC-A symbol and used mainly in North America.",,true,,false,"Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.",GS1 General Specifications — check-digit calculation,https://www.gs1.org/standards/barcodes/ean-upc,A correct check digit means the digits are internally consistent. It does not mean the GTIN has been allocated to a company or assigned to a product — this endpoint queries no GS1 registry and holds no product catalogue.
gtin13,GTIN-13 (EAN-13),"GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",0-9,[13],13,1,0-9,last character,"Global GS1 key, printed as an EAN-13 symbol.",,true,,false,"Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.",GS1 General Specifications — check-digit calculation,https://www.gs1.org/standards/barcodes/ean-upc,A correct check digit means the digits are internally consistent. It does not mean the GTIN has been allocated to a company or assigned to a product — this endpoint queries no GS1 registry and holds no product catalogue.
gtin14,GTIN-14 (ITF-14 case code),"GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",0-9,[14],14,1,0-9,last character,Global GS1 key for higher packaging levels; the first digit is the packaging indicator.,,true,,false,"Swapping two adjacent digits whose values differ by five is undetected (05↔50, 16↔61, 27↔72, 38↔83, 49↔94). Every other adjacent transposition changes the check digit.",GS1 General Specifications — check-digit calculation,https://www.gs1.org/standards/barcodes/ean-upc,A correct check digit means the digits are internally consistent. It does not mean the GTIN has been allocated to a company or assigned to a product — this endpoint queries no GS1 registry and holds no product catalogue.

GET /api/check-digits/validate

Returns a structured verdict for any input: malformed values produce valid=false with ordered reason codes, never an error page.

Live requestRuns against the public API
No key required
GET/api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7

Request parameters

Identifier scheme to apply. 'upca' is an alias for 'gtin12'. 'npi' and 'aba' are United States schemes, and the 'vin' check character is only enforced where the world manufacturer identifier's ISO 3780 region block is North American (1-5) or Chinese (L).

The identifier to check, with or without spaces and hyphens. Whitespace is preserved when normalize=false so it shows up as an invalid character.

Remove ASCII spaces and hyphens before checking. ASCII letters are uppercased either way, because every scheme's alphabet is uppercase-only.

Also enforce the scheme's structural rules (prefixes, VIN model-year code, Federal Reserve routing symbol). Schemes with no further rules answer with a warning.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7"
const res = await fetch("https://randomapi.dev/api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 4
scheme enum required

Identifier scheme to apply. 'upca' is an alias for 'gtin12'. 'npi' and 'aba' are United States schemes, and the 'vin' check character is only enforced where the world manufacturer identifier's ISO 3780 region block is North American (1-5) or Chinese (L).

allowed: luhn | gtin8 | gtin12 | gtin13 | gtin14 | upca | isbn10 | isbn13 | issn | ismn | imei | isin | lei | vin | npi | aba | iso7064-mod11-2 | iso7064-mod11-10 | iso7064-mod97-10
example: scheme=isbn13
value string required

The identifier to check, with or without spaces and hyphens. Whitespace is preserved when normalize=false so it shows up as an invalid character.

allowed: 1 – 64
example: value=978-0-306-40615-7
normalize boolean

Remove ASCII spaces and hyphens before checking. ASCII letters are uppercased either way, because every scheme's alphabet is uppercase-only.

default: true
example: normalize=true
strict boolean

Also enforce the scheme's structural rules (prefixes, VIN model-year code, Federal Reserve routing symbol). Schemes with no further rules answer with a warning.

default: false
example: strict=true
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=scheme,canonicalScheme
exclude list

Return all fields except these (comma-separated).

example: exclude=notes
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 18
scheme string

Scheme id exactly as requested.

example: isbn13

canonicalScheme string

Scheme actually applied — 'upca' resolves to 'gtin12'.

example: isbn13

input string

The value exactly as supplied.

example: 978-0-306-40615-7

normalized string

Uppercased value, with ASCII spaces and hyphens removed when normalize is true.

example: 9780306406157

valid boolean

True only for this endpoint's checks: alphabet, length, check character (where applicable) and any strict rules. It never means the identifier was issued, assigned or registered.

example: true

reasons string[]

Stable ordered failure codes — EMPTY_AFTER_NORMALIZATION, INVALID_CHARACTERS, WRONG_LENGTH, CHECK_CHARACTER_MISMATCH, STRICT_INVALID_PREFIX, STRICT_INVALID_MODEL_YEAR_CODE, STRICT_INVALID_ROUTING_SYMBOL. Empty exactly when valid is true.

example: []

payload string nullable

The value without its check characters, or null when the value was too malformed to split.

example: 978030640615

checkCharacter string nullable

The check character(s) found in the input, or null when the value could not be split.

example: 7

expectedCheckCharacter string nullable

What the scheme's algorithm computes for that payload, or null when it could not be computed.

example: 7

checkCharacterValid boolean

Whether the supplied check character equals the computed one. Reported even when checkDigitApplicable is false, so a European VIN's position-9 result is still visible.

example: true

checkDigitApplicable boolean

Whether this endpoint holds the check character against the value. Always true except for a complete VIN whose world manufacturer identifier falls outside the ISO 3780 North American (1-5) and Chinese (L) region blocks, where a mismatch never makes the VIN invalid. That is inferred from the WMI alone, so false means 'not determinable from the VIN alone', not 'not required' — 49 CFR 565 requires a check digit on any vehicle built for sale in the US whatever its WMI. Read checkCharacterValid for the strict answer.

example: true

actualLength integer

Length of the normalized value.

example: 13

expectedLengths integer[]

Accepted total lengths, or an empty array for a variable-length scheme.

example: [13]

minLength integer

Smallest accepted total length.

example: 13

invalidCharacters object[]

Every character outside the scheme's alphabet, in input order, as { index, character } with a zero-based index into the normalized value. When the length is wrong the check position cannot be located, so every character is tested against the scheme's full alphabet rather than the narrower check-position one. Empty when the alphabet check passed.

example: [{"index":4,"character":"#"}]

algorithm string

The algorithm applied, in one sentence.

example: GS1 modulo-10 over the thirteen-digit Bookland EAN (weights 3 and 1 alternating from the right)

scope string

Where this scheme and its check character actually apply.

example: Global.

notes string[]

Situational explanations — VIN regional applicability, the upca alias, a 16-digit IMEISV, a failed strict rule, and the GS1 prefix caveat on every GTIN form. Empty when nothing needs saying.

example: []

Documented examples

Build-generated requests and complete responses
6
Check a published ISBN-13
GET /api/check-digits/validate?scheme=isbn13&value=978-0-306-40615-7
{
  "data": {
    "scheme": "isbn13",
    "canonicalScheme": "isbn13",
    "input": "978-0-306-40615-7",
    "normalized": "9780306406157",
    "valid": true,
    "reasons": [],
    "payload": "978030640615",
    "checkCharacter": "7",
    "expectedCheckCharacter": "7",
    "checkCharacterValid": true,
    "checkDigitApplicable": true,
    "actualLength": 13,
    "expectedLengths": [
      13
    ],
    "minLength": 13,
    "invalidCharacters": [],
    "algorithm": "GS1 modulo-10 over the thirteen-digit Bookland EAN (weights 3 and 1 alternating from the right)",
    "scope": "Global.",
    "notes": []
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "isbn13",
      "value": "978-0-306-40615-7",
      "normalize": true,
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Validate an IMEI
GET /api/check-digits/validate?scheme=imei&value=490154203237518
{
  "data": {
    "scheme": "imei",
    "canonicalScheme": "imei",
    "input": "490154203237518",
    "normalized": "490154203237518",
    "valid": true,
    "reasons": [],
    "payload": "49015420323751",
    "checkCharacter": "8",
    "expectedCheckCharacter": "8",
    "checkCharacterValid": true,
    "checkDigitApplicable": true,
    "actualLength": 15,
    "expectedLengths": [
      15
    ],
    "minLength": 15,
    "invalidCharacters": [],
    "algorithm": "Luhn modulo-10 over the fourteen TAC and serial digits",
    "scope": "Global, for GSM/UMTS/LTE/NR mobile equipment.",
    "notes": []
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "imei",
      "value": "490154203237518",
      "normalize": true,
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
A European VIN has no position-9 check digit
GET /api/check-digits/validate?scheme=vin&value=WVWZZZ1JZXW000010
{
  "data": {
    "scheme": "vin",
    "canonicalScheme": "vin",
    "input": "WVWZZZ1JZXW000010",
    "normalized": "WVWZZZ1JZXW000010",
    "valid": true,
    "reasons": [],
    "payload": "WVWZZZ1JXW000010",
    "checkCharacter": "Z",
    "expectedCheckCharacter": "1",
    "checkCharacterValid": false,
    "checkDigitApplicable": false,
    "actualLength": 17,
    "expectedLengths": [
      17
    ],
    "minLength": 17,
    "invalidCharacters": [],
    "algorithm": "ISO 3779 transliteration, weights 8-7-6-5-4-3-2-10-0-9-8-7-6-5-4-3-2, modulo 11; remainder 10 is written as X",
    "scope": "The VIN is global; the position-9 check character is not. 49 CFR 565 requires one on every vehicle manufactured for sale in the United States and GB 16735 requires one in China, while no United Kingdom or European Union rule does. A VIN does not record which market it was built for, so this endpoint infers applicability from the ISO 3780 region block of the world manufacturer identifier alone and never marks a VIN outside the 1-5 and L blocks invalid on the check character.",
    "notes": [
      "The world manufacturer identifier 'WVW' begins with 'W', outside the ISO 3780 North American (1-5) and Chinese (L) region blocks, so position 9 is reported but never makes this VIN invalid. That is inferred from the WMI alone and is not the regulation: 49 CFR 565 requires a check digit on every vehicle manufactured for sale in the United States whatever its WMI, so a US-market European, Japanese or Korean vehicle does carry one. Read checkCharacterValid when you need the strict answer."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "vin",
      "value": "WVWZZZ1JZXW000010",
      "normalize": true,
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Explain a mistyped EAN-13
GET /api/check-digits/validate?scheme=gtin13&value=5901234123458
{
  "data": {
    "scheme": "gtin13",
    "canonicalScheme": "gtin13",
    "input": "5901234123458",
    "normalized": "5901234123458",
    "valid": false,
    "reasons": [
      "CHECK_CHARACTER_MISMATCH"
    ],
    "payload": "590123412345",
    "checkCharacter": "8",
    "expectedCheckCharacter": "7",
    "checkCharacterValid": false,
    "checkDigitApplicable": true,
    "actualLength": 13,
    "expectedLengths": [
      13
    ],
    "minLength": 13,
    "invalidCharacters": [],
    "algorithm": "GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",
    "scope": "Global GS1 key, printed as an EAN-13 symbol.",
    "notes": [
      "The leading digits identify the GS1 Member Organisation that issued the company prefix. They are not a country of origin, a country of manufacture or a company address."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "gtin13",
      "value": "5901234123458",
      "normalize": true,
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Strict mode rejects a non-ISBN prefix
GET /api/check-digits/validate?scheme=isbn13&value=5901234123457&strict=true
{
  "data": {
    "scheme": "isbn13",
    "canonicalScheme": "isbn13",
    "input": "5901234123457",
    "normalized": "5901234123457",
    "valid": false,
    "reasons": [
      "STRICT_INVALID_PREFIX"
    ],
    "payload": "590123412345",
    "checkCharacter": "7",
    "expectedCheckCharacter": "7",
    "checkCharacterValid": true,
    "checkDigitApplicable": true,
    "actualLength": 13,
    "expectedLengths": [
      13
    ],
    "minLength": 13,
    "invalidCharacters": [],
    "algorithm": "GS1 modulo-10 over the thirteen-digit Bookland EAN (weights 3 and 1 alternating from the right)",
    "scope": "Global.",
    "notes": [
      "ISBN-13 values carry the Bookland prefix 978 or 979 (excluding 979-0). '590' is a valid GTIN-13 but not an ISBN."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "isbn13",
      "value": "5901234123457",
      "normalize": true,
      "strict": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Check an ISIN
GET /api/check-digits/validate?scheme=isin&value=US0378331005
{
  "data": {
    "scheme": "isin",
    "canonicalScheme": "isin",
    "input": "US0378331005",
    "normalized": "US0378331005",
    "valid": true,
    "reasons": [],
    "payload": "US037833100",
    "checkCharacter": "5",
    "expectedCheckCharacter": "5",
    "checkCharacterValid": true,
    "checkDigitApplicable": true,
    "actualLength": 12,
    "expectedLengths": [
      12
    ],
    "minLength": 12,
    "invalidCharacters": [],
    "algorithm": "Letters expanded A=10…Z=35, then Luhn modulo-10 over the resulting decimal string",
    "scope": "Global, for securities.",
    "notes": []
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/validate",
    "params": {
      "scheme": "isin",
      "value": "US0378331005",
      "normalize": true,
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

GET /api/check-digits/compute

Takes the identifier without its check character(s) and returns both the character and the completed value. A malformed payload answers computable=false with reason codes.

Live requestRuns against the public API
No key required
GET/api/check-digits/compute?scheme=gtin13&value=590123412345

Request parameters

Identifier scheme to apply. 'upca' is an alias for 'gtin12'. 'npi' and 'aba' are United States schemes, and the 'vin' check character is only enforced where the world manufacturer identifier's ISO 3780 region block is North American (1-5) or Chinese (L).

The payload without its check character(s) — twelve digits for a GTIN-13, nine for an ISBN-10 or NPI, eighteen for a LEI. For a VIN, pass either the sixteen characters around position 9 or a full seventeen-character VIN whose position 9 is a placeholder.

Remove ASCII spaces and hyphens before checking. ASCII letters are uppercased either way, because every scheme's alphabet is uppercase-only.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/check-digits/compute?scheme=gtin13&value=590123412345"
const res = await fetch("https://randomapi.dev/api/check-digits/compute?scheme=gtin13&value=590123412345");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/check-digits/compute?scheme=gtin13&value=590123412345").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/check-digits/compute?scheme=gtin13&value=590123412345"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 3
scheme enum required

Identifier scheme to apply. 'upca' is an alias for 'gtin12'. 'npi' and 'aba' are United States schemes, and the 'vin' check character is only enforced where the world manufacturer identifier's ISO 3780 region block is North American (1-5) or Chinese (L).

allowed: luhn | gtin8 | gtin12 | gtin13 | gtin14 | upca | isbn10 | isbn13 | issn | ismn | imei | isin | lei | vin | npi | aba | iso7064-mod11-2 | iso7064-mod11-10 | iso7064-mod97-10
example: scheme=gtin13
value string required

The payload without its check character(s) — twelve digits for a GTIN-13, nine for an ISBN-10 or NPI, eighteen for a LEI. For a VIN, pass either the sixteen characters around position 9 or a full seventeen-character VIN whose position 9 is a placeholder.

allowed: 1 – 64
example: value=590123412345
normalize boolean

Remove ASCII spaces and hyphens before checking. ASCII letters are uppercased either way, because every scheme's alphabet is uppercase-only.

default: true
example: normalize=true
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=scheme,canonicalScheme
exclude list

Return all fields except these (comma-separated).

example: exclude=notes
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 15
scheme string

Scheme id exactly as requested.

example: gtin13

canonicalScheme string

Scheme actually applied — 'upca' resolves to 'gtin12'.

example: gtin13

input string

The payload exactly as supplied.

example: 590123412345

payload string nullable

Normalized payload used for the computation, or null when it was not computable.

example: 590123412345

checkCharacter string nullable

The computed check character(s), or null when not computable.

example: 7

value string nullable

The complete identifier, with the check character inserted where the scheme puts it (position 9 for a VIN, otherwise appended). Null when not computable.

example: 5901234123457

computable boolean

Whether a check character could be computed at all.

example: true

reasons string[]

Stable ordered failure codes — EMPTY_AFTER_NORMALIZATION, INVALID_CHARACTERS, WRONG_PAYLOAD_LENGTH. Empty exactly when computable is true.

example: []

invalidCharacters object[]

Every character outside the scheme's alphabet, in input order, as { index, character } with a zero-based index into the normalized value. When the length is wrong the check position cannot be located, so every character is tested against the scheme's full alphabet rather than the narrower check-position one. Empty when the alphabet check passed.

example: [{"index":4,"character":"#"}]

expectedPayloadLengths integer[]

Accepted payload lengths (total length minus the check characters). Empty for variable-length schemes; VIN accepts 16 or a full 17.

example: [12]

actualPayloadLength integer

Length of the normalized payload as supplied.

example: 12

checkDigitApplicable boolean

Whether this endpoint would hold the computed character against the completed value. Always true except for a VIN whose world manufacturer identifier falls outside the ISO 3780 North American (1-5) and Chinese (L) region blocks — an inference from the WMI, not the regulation, so the value is still returned with the character in place and an explanatory note.

example: true

algorithm string

The algorithm applied, in one sentence.

example: GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten

scope string

Where this scheme and its check character actually apply.

example: Global GS1 key, printed as an EAN-13 symbol.

notes string[]

Situational explanations, such as a VIN placeholder form or the GS1 prefix caveat.

example: []

Documented examples

Build-generated requests and complete responses
5
EAN-13 check digit for twelve digits
GET /api/check-digits/compute?scheme=gtin13&value=590123412345
{
  "data": {
    "scheme": "gtin13",
    "canonicalScheme": "gtin13",
    "input": "590123412345",
    "payload": "590123412345",
    "checkCharacter": "7",
    "value": "5901234123457",
    "computable": true,
    "reasons": [],
    "invalidCharacters": [],
    "expectedPayloadLengths": [
      12
    ],
    "actualPayloadLength": 12,
    "checkDigitApplicable": true,
    "algorithm": "GS1 modulo-10: weights 3 and 1 alternating from the right, subtracted from the next multiple of ten",
    "scope": "Global GS1 key, printed as an EAN-13 symbol.",
    "notes": [
      "The leading digits identify the GS1 Member Organisation that issued the company prefix. They are not a country of origin, a country of manufacture or a company address."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/compute",
    "params": {
      "scheme": "gtin13",
      "value": "590123412345",
      "normalize": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
An ISBN-10 whose check character is X
GET /api/check-digits/compute?scheme=isbn10&value=043942089
{
  "data": {
    "scheme": "isbn10",
    "canonicalScheme": "isbn10",
    "input": "043942089",
    "payload": "043942089",
    "checkCharacter": "X",
    "value": "043942089X",
    "computable": true,
    "reasons": [],
    "invalidCharacters": [],
    "expectedPayloadLengths": [
      9
    ],
    "actualPayloadLength": 9,
    "checkDigitApplicable": true,
    "algorithm": "Modulo-11 with descending weights 10…2; remainder 10 is written as X",
    "scope": "Global. Withdrawn for new assignments in 2007 but still present in legacy catalogues; every ISBN-10 has an equivalent 978-prefixed ISBN-13.",
    "notes": []
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/compute",
    "params": {
      "scheme": "isbn10",
      "value": "043942089",
      "normalize": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
VIN check character from a 16-character payload
GET /api/check-digits/compute?scheme=vin&value=1HGCM8263A004352
{
  "data": {
    "scheme": "vin",
    "canonicalScheme": "vin",
    "input": "1HGCM8263A004352",
    "payload": "1HGCM8263A004352",
    "checkCharacter": "3",
    "value": "1HGCM82633A004352",
    "computable": true,
    "reasons": [],
    "invalidCharacters": [],
    "expectedPayloadLengths": [
      16,
      17
    ],
    "actualPayloadLength": 16,
    "checkDigitApplicable": true,
    "algorithm": "ISO 3779 transliteration, weights 8-7-6-5-4-3-2-10-0-9-8-7-6-5-4-3-2, modulo 11; remainder 10 is written as X",
    "scope": "The VIN is global; the position-9 check character is not. 49 CFR 565 requires one on every vehicle manufactured for sale in the United States and GB 16735 requires one in China, while no United Kingdom or European Union rule does. A VIN does not record which market it was built for, so this endpoint infers applicability from the ISO 3780 region block of the world manufacturer identifier alone and never marks a VIN outside the 1-5 and L blocks invalid on the check character.",
    "notes": [
      "The world manufacturer identifier '1HG' begins with '1', the ISO 3780 North American region block, so this VIN is treated as one 49 CFR 565 covers and the position-9 check character is required."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/compute",
    "params": {
      "scheme": "vin",
      "value": "1HGCM8263A004352",
      "normalize": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
LEI check-digit pair
GET /api/check-digits/compute?scheme=lei&value=L3I9ZG2KFGXZ61BMYR
{
  "data": {
    "scheme": "lei",
    "canonicalScheme": "lei",
    "input": "L3I9ZG2KFGXZ61BMYR",
    "payload": "L3I9ZG2KFGXZ61BMYR",
    "checkCharacter": "72",
    "value": "L3I9ZG2KFGXZ61BMYR72",
    "computable": true,
    "reasons": [],
    "invalidCharacters": [],
    "expectedPayloadLengths": [
      18
    ],
    "actualPayloadLength": 18,
    "checkDigitApplicable": true,
    "algorithm": "ISO/IEC 7064 MOD 97-10 over the twenty characters with letters expanded A=10…Z=35; a valid LEI leaves remainder 1",
    "scope": "Global, for legal entities in financial transactions.",
    "notes": [
      "ISO 17442 reserves characters 5 and 6 as '00', but some registered LEIs do not follow that convention, so this endpoint does not treat it as a validity rule."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/compute",
    "params": {
      "scheme": "lei",
      "value": "L3I9ZG2KFGXZ61BMYR",
      "normalize": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
NPI check digit
GET /api/check-digits/compute?scheme=npi&value=123456789
{
  "data": {
    "scheme": "npi",
    "canonicalScheme": "npi",
    "input": "123456789",
    "payload": "123456789",
    "checkCharacter": "3",
    "value": "1234567893",
    "computable": true,
    "reasons": [],
    "invalidCharacters": [],
    "expectedPayloadLengths": [
      9
    ],
    "actualPayloadLength": 9,
    "checkDigitApplicable": true,
    "algorithm": "Luhn modulo-10 over 80840 followed by the nine-digit payload",
    "scope": "United States only. The National Provider Identifier is issued by CMS for US health care providers; it has no meaning elsewhere.",
    "notes": []
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/compute",
    "params": {
      "scheme": "npi",
      "value": "123456789",
      "normalize": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

GET /api/check-digits/convert

Detects the source form from its length, verifies its own check character, then re-expresses it as the target and recomputes the check character.

Live requestRuns against the public API
No key required
GET/api/check-digits/convert?value=036000291452&to=gtin13

Request parameters

Source identifier: a GTIN-8, ISBN-10, GTIN-12/UPC-A, GTIN-13/ISBN-13 or GTIN-14. Spaces and hyphens are always removed. Its own check character must be correct.

Target form. Conversions that do not exist — a GTIN-14 above indicator 0, a GTIN-13 without a leading zero to UPC-A, a 979-prefixed ISBN-13 to ISBN-10 — return a 400 explaining why.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/check-digits/convert?value=036000291452&to=gtin13"
const res = await fetch("https://randomapi.dev/api/check-digits/convert?value=036000291452&to=gtin13");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/check-digits/convert?value=036000291452&to=gtin13").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/check-digits/convert?value=036000291452&to=gtin13"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 2
value string required

Source identifier: a GTIN-8, ISBN-10, GTIN-12/UPC-A, GTIN-13/ISBN-13 or GTIN-14. Spaces and hyphens are always removed. Its own check character must be correct.

allowed: 1 – 64
example: value=036000291452
to enum required

Target form. Conversions that do not exist — a GTIN-14 above indicator 0, a GTIN-13 without a leading zero to UPC-A, a 979-prefixed ISBN-13 to ISBN-10 — return a 400 explaining why.

allowed: gtin13 | gtin14 | upca | isbn10 | isbn13
example: to=gtin13
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=input,normalized
exclude list

Return all fields except these (comma-separated).

example: exclude=notes
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 9
input string

The source value exactly as supplied.

example: 036000291452

normalized string

Uppercased source with ASCII spaces and hyphens removed.

example: 036000291452

sourceForm string

Detected source form: gtin8, isbn10, gtin12, gtin13 or gtin14.

example: gtin12

sourceCheckCharacter string

The source's own (verified) check character.

example: 2

to string

Requested target form.

example: gtin13

value string

The converted identifier, with its check character recomputed for the target form.

example: 0036000291452

checkCharacter string

Check character of the converted value.

example: 2

checkCharacterChanged boolean

Whether the converted value's check character literally differs from the source's. Zero-padding between GTIN forms never changes it, because GS1 weights run from the right. An ISBN-10 ↔ ISBN-13 conversion always recomputes it under the other algorithm, but about one such conversion in ten lands on the same character and so reports false.

example: false

notes string[]

What the conversion did and any caveat that applies to it.

example: []

Documented examples

Build-generated requests and complete responses
4
UPC-A to GTIN-13
GET /api/check-digits/convert?value=036000291452&to=gtin13
{
  "data": {
    "input": "036000291452",
    "normalized": "036000291452",
    "sourceForm": "gtin12",
    "sourceCheckCharacter": "2",
    "to": "gtin13",
    "value": "0036000291452",
    "checkCharacter": "2",
    "checkCharacterChanged": false,
    "notes": [
      "GS1 represents a shorter GTIN in a longer data field by right-justifying it with leading zeros. The check digit is unchanged because GS1 weights are assigned from the right."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/convert",
    "params": {
      "value": "036000291452",
      "to": "gtin13"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
ISBN-13 back to ISBN-10
GET /api/check-digits/convert?value=9780306406157&to=isbn10
{
  "data": {
    "input": "9780306406157",
    "normalized": "9780306406157",
    "sourceForm": "gtin13",
    "sourceCheckCharacter": "7",
    "to": "isbn10",
    "value": "0306406152",
    "checkCharacter": "2",
    "checkCharacterChanged": true,
    "notes": [
      "This GTIN-13 carries a Bookland prefix, so it is also an ISBN-13.",
      "The 978 prefix is dropped and the modulo-11 check character (0-9 or X) is recomputed from the remaining nine digits."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/convert",
    "params": {
      "value": "9780306406157",
      "to": "isbn10"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
ISBN-10 forward to ISBN-13
GET /api/check-digits/convert?value=0-306-40615-2&to=isbn13
{
  "data": {
    "input": "0-306-40615-2",
    "normalized": "0306406152",
    "sourceForm": "isbn10",
    "sourceCheckCharacter": "2",
    "to": "isbn13",
    "value": "9780306406157",
    "checkCharacter": "7",
    "checkCharacterChanged": true,
    "notes": [
      "ISBN-10 uses a modulo-11 check character (0-9 or X) while ISBN-13 and the GTIN forms use the GS1 modulo-10 check digit, so the check character is recomputed rather than carried over."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/convert",
    "params": {
      "value": "0-306-40615-2",
      "to": "isbn13"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
GTIN-13 to a case-level GTIN-14
GET /api/check-digits/convert?value=5901234123457&to=gtin14
{
  "data": {
    "input": "5901234123457",
    "normalized": "5901234123457",
    "sourceForm": "gtin13",
    "sourceCheckCharacter": "7",
    "to": "gtin14",
    "value": "05901234123457",
    "checkCharacter": "7",
    "checkCharacterChanged": false,
    "notes": [
      "GS1 represents a shorter GTIN in a longer data field by right-justifying it with leading zeros. The check digit is unchanged because GS1 weights are assigned from the right.",
      "Packaging indicator 0 identifies the base trade item. A GTIN-14 built with indicator 0 keeps the source check digit; indicators 1-9 describe higher packaging levels and are assigned by the brand owner, not derived."
    ]
  },
  "meta": {
    "endpoint": "check-digits",
    "route": "/convert",
    "params": {
      "value": "5901234123457",
      "to": "gtin14"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

About this API

Coverage & behavior

Nineteen check-character schemes, each implemented straight from its published algorithm and each reporting which rule failed, not just a boolean. /validate checks an identifier, /compute returns the character a payload is missing, /convert moves between equivalent GTIN and ISBN forms, and the root route documents every scheme's algorithm, alphabet, length rules and error-detection limits.

A valid check digit means well-formed — nothing more. It does not mean the identifier was issued, assigned, registered, listed, enumerated or is tradeable. This endpoint holds no product catalogue, securities master, vehicle history, device database or provider registry, and it makes no network calls, so it cannot tell you whether a number belongs to anything real.

Regional scope matters, and we say exactly how far we can see. The VIN check character at position 9 is required by 49 CFR 565 on vehicles manufactured for sale in the United States and by GB 16735 in China; no United Kingdom or European Union rule requires one. A VIN does not record which market it was built for, so scheme=vin reads the ISO 3780 region block of the world manufacturer identifier and returns checkDigitApplicable: false outside the 1-5 and L blocks, where a position-9 mismatch is reported in checkCharacterValid but never makes valid false. That is an inference, not the regulation: a US-market BMW, Toyota or Hyundai carries a mandatory check digit under a W, J or K WMI, so checkDigitApplicable: false means "not determinable from the VIN alone" — read checkCharacterValid when you need the strict answer. npi and aba are United States schemes and say so in their own scope field.

Error detection is not universal, so each scheme states its own limits. Mod-10 systems cannot see every transposition: Luhn (and therefore IMEI, NPI and the last step of ISIN) misses the 09 ↔ 90 swap, while the GS1 and ABA weightings miss adjacent digits five apart. The modulus-11 and modulus-97 systems — ISBN-10, ISSN, ISO 7064 MOD 11-2 and MOD 97-10 — catch every adjacent transposition; ISO 7064 MOD 11,10 misses a small minority, and ISIN misses every adjacent letter-letter swap, the country prefix included. ISIN, LEI and VIN do not even catch every single-character substitution: VIN's transliteration table is many-to-one, so A and J are indistinguishable to the check character, while ISIN and LEI expand letters into two digits, so a letter-for-digit substitution changes the arithmetic's shape rather than just one term. Every scheme record carries detectsAllSingleCharacterErrors and detectsAllAdjacentTranspositions, plus a plain-English description of exactly what slips through when something does.

Errors are structured, not thrown. A wrong length or an out-of-alphabet character produces a valid: false record with ordered reasons codes and an invalidCharacters list naming each offending character and its index. Beyond the platform's ordinary parameter validation — a missing value, a value over 64 characters, an unrecognized scheme or to — the only 400 this endpoint raises is a /convert request that is genuinely impossible.

strict=false (the default) checks alphabet, length and check character only. strict=true adds the specification's structural rules where they exist: the ISBN-13 Bookland prefix (978, or 979 other than 979-0, which is the ISMN prefix), the ISMN 9790 prefix, the two-letter ISIN prefix, the North-American VIN model-year code and the allocated Federal Reserve routing symbols. For the fourteen schemes with no further rules, strict=true returns a warning saying so rather than pretending to do more.

Deliberate exclusions. National identity numbers are out of scope entirely. GS1 prefix → company or country lookup is out of scope: the table is not ours to redistribute, and "prefix equals country of origin" is false in any case — the leading digits identify the GS1 Member Organisation that issued the company prefix. ISBN hyphenation is out of scope because the ISBN range message is not redistributable. IBAN national layouts stay in the ibans endpoint; this one owns the generic ISO 7064 MOD 97-10 algorithm. GS1 and ISO standards texts are paywalled: we implement and cite the published algorithms, we do not reproduce the standards.

Use it for

  • Validate an EAN-13 or UPC-A payload before sending it to a label printer
  • Compute the missing ISBN-10 or ISBN-13 check character during a catalogue import
  • Reject mistyped IMEIs in a device-enrolment form without shipping a Luhn implementation
  • Convert a 12-digit UPC-A into the GTIN-13 and GTIN-14 forms a warehouse system expects
  • Tell a support agent exactly which rule a rejected VIN, ISIN or LEI broke

Frequently asked questions

How do I validate an IMEI number?

Call /api/check-digits/validate?scheme=imei&value=490154203237518. It runs the Luhn check that 3GPP TS 23.003 defines over the fourteen TAC and serial digits. A pass means the fifteen digits are well formed — it does not mean the device exists or that the Type Allocation Code was ever issued.

How is the EAN-13 or UPC check digit calculated?

GS1 weights the data digits 3 and 1 alternately from the right, sums them and subtracts the total from the next multiple of ten. /api/check-digits/compute?scheme=gtin13&value=590123412345 returns the digit, and the identical rule covers GTIN-8, GTIN-12/UPC-A and GTIN-14.

Does a GS1 or EAN prefix tell you the country of origin?

No. The leading digits identify the GS1 Member Organisation that issued the company prefix — not where a product was made, nor where the company is based. A firm can join GS1 in one country and manufacture anywhere, so this endpoint deliberately ships no prefix-to-country table.

Why does a European VIN fail other check digit calculators?

Because position 9 is a check character only where a regulator requires it — 49 CFR 565 in the United States, GB 16735 in China — and no UK or EU rule does. A VIN does not record its market, so this endpoint reads the ISO 3780 region block of the world manufacturer identifier: outside the 1-5 and L blocks it returns checkDigitApplicable: false and never lets a position-9 mismatch make valid false. That is an inference, not the regulation, so read checkCharacterValid for the strict answer — a US-market BMW or Toyota does carry a mandatory check digit.

Can I convert an ISBN-13 back to an ISBN-10?

Only when the prefix is 978. /api/check-digits/convert?value=9780306406157&to=isbn10 drops the prefix and recomputes the modulo-11 character. A 979-prefixed ISBN-13 has no ISBN-10 at all and returns a 400 that says exactly that.

Which typing errors does a check digit actually catch?

Every scheme here catches all single-character substitutions except ISIN, LEI and VIN, where expanding or transliterating letters into digits either collapses characters onto the same contribution (VIN) or changes the length of the string being weighed (ISIN, LEI — so 0 typed as O can slip through). Adjacent transpositions vary: Luhn misses only 09 ↔ 90, the GS1 and ABA mod-10 weightings miss digits five apart, ISO 7064 MOD 11,10 misses a small minority, ISIN misses every letter-letter swap, and the modulus-11 and modulus-97 systems miss none. Each scheme record spells out its own limits.

Standards & references