ISIN check digit
For the body US037833100 the check digit is 5, giving the full ISIN US0378331005. Complete a securities identifier before you print or store it, or check a twelve-character ISIN that arrived in a partner's file. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Code
- US037833100
- Converted
- 3028037833100
- Calculation mode
- Compute
- Input
- US037833100
- Country code
- US
An International Securities Identification Number (ISIN) is the twelve-character code that uniquely labels a security across markets under ISO 6166. The first two characters are a country code, the next nine are the national securities identifying number (NSIN), and the twelfth is a single numeric check digit produced by converting letters to numbers and running the Luhn algorithm. This capability implements that official rule only: compute mode accepts exactly eleven alphanumeric characters and returns the check digit plus the full twelve-character ISIN; validate mode accepts a full twelve-character ISIN and reports whether the trailing digit matches the recomputed expected value.
How the ISIN Luhn check digit is calculated
Under ISO 6166 an ISIN is always twelve characters: two uppercase letters for the country or region of issue, nine alphanumeric characters for the NSIN (often a zero-padded national number such as a CUSIP or SEDOL), and one final digit that is the check character. To compute that digit, take the eleven-character body and expand every letter into two decimal digits by the fixed mapping A equals ten through Z equals thirty-five, while decimal digits stay single digits.
The result is a pure digit string whose length depends on how many letters appear in the body—country codes alone always contribute four digits because both characters are letters. Apply the classic Luhn algorithm from the right of that expanded string: double every second digit starting with the rightmost body digit, because once the check digit is appended that rightmost body digit sits in position two from the right of the full number.
When twice a digit is greater than nine, subtract nine (equivalently sum the tens and units of the product). Add every weighted value; the check digit is ten minus that sum modulo ten, modulo ten again so the complete digit sequence including the check digit has a Luhn total divisible by ten. Validation recomputes the expected digit from the first eleven characters and compares it to the twelfth, which must always be a decimal digit zero through nine.
The algorithm is deterministic and local: no issuer registry call, no clock, and no randomness. Compared with card Luhn or IMEI Luhn tools, the search intent here is narrow: people who need an ISIN check digit calculator for an eleven-character body or a twelve-character securities ISIN checker, not a payment or device tool.
Input contract, modes, and error behaviour
Send a code field that contains only letters A through Z and digits zero through nine after trim and uppercasing. Wrong length is an explicit error that names the mode and the length you sent—eleven for compute, twelve for validate—so client forms can show “need eleven characters” without guessing. Empty strings, missing code, invalid mode values, a non-digit twelfth character on validate, and a body that fails the two-letter plus nine-alnum shape all fail before any Luhn sum runs and are not billed.
Prefer compute when you mint or complete ISINs for master data and labels; prefer validate when you gate a trade, import, or lookup on a full ISIN from a user, partner file, or market data feed. Failed validation tasks that reject bad shape are not charged; a well-formed twelve-character string that simply has the wrong check digit returns valid false without throwing.
Where ISIN check digits fit real workflows
Issuers, agents, and numbering agencies receive national codes and must append the official Luhn check digit before an ISIN is printed on prospectuses, corporate actions, or regulatory filings. Broker and custodian onboarding forms validate twelve-character ISINs at entry so a single transposition does not open a phantom position or a failed settlement instruction. ETL jobs that load instrument master files walk every ISIN column in a CSV or FIX security definition, call validate mode, and quarantine rows where valid is false—catching both human edits and off-by-one bugs in generators.
Do not treat a passing ISIN check as proof that the security is listed, liquid, or free of corporate actions; it only proves the Luhn digit is consistent with the expanded country and NSIN under the standard ISO 6166 weights used for international securities identification.
What you can do with it
Audit ISIN columns in security inventories
Batch-validate every twelve-character ISIN in a middle-office, custodian, or market-data CSV and quarantine rows whose check digit no longer matches the recomputed expected value.
FAQ
What is an ISIN check digit?
It is the twelfth character of an ISIN, a digit zero through nine computed with the Luhn algorithm after expanding letters A–Z to 10–35 over the first eleven characters, so typing and scanning errors are usually caught before the code is stored or traded.
Is the ISIN check digit tool free?
The browser tool is free and runs locally.
What do the parts of an ISIN mean?
The first two letters are the country or region of issue, the next nine characters are the national securities number, and the twelfth is the check digit. In US0378331005, US is the country, 037833100 the national number and 5 the check digit.
How is the ISIN check digit calculated?
Each letter is replaced by two digits, A as ten up to Z as thirty-five, while digits stay as they are. Then the Luhn rule runs from the right: double every second digit starting with the last one, subtract nine above nine, add up and take ten minus the remainder.
Does a valid ISIN mean the security is listed?
No. A correct check digit only shows that the twelve characters are consistent with each other. No issuer database is consulted, so it says nothing about whether the security is listed or settled.
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/isin \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"code":"US037833100"}'const res = await fetch("https://api.kit.forhosting.com/enc/isin", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"code": "US037833100"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/isin",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"code": "US037833100"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/isin", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"code":"US037833100"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"code":"US037833100"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/isin", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"code": "US037833100"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.isin",
"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-alphanumeric input, wrong lengths, and malformed country or NSIN shapes fail with invalid_input instead of silent stripping, so you never persist a half-cleaned identifier. The same pure arithmetic runs free in the browser and at the published API price, with no network lookup of issuer databases and no claim that a valid checksum means the security is listed, settled, or free of corporate-action issues.
Input contract, modes, and error behaviour
Spaces, hyphens, symbols, and lowercase-only punctuation are rejected as non-alphanumeric input with invalid_input so a silently stripped value never reaches storage. Mode compute is the default: the engine requires exactly eleven characters with a two-letter country code followed by a nine-character alphanumeric NSIN, returns check_digit as a one-character string, returns with_check as the twelve-character ISIN you can print or persist, and also returns converted (the expanded digit string), country_code, and nsin for audit trails. Mode validate requires exactly twelve characters whose last character is a digit; the response reports valid true when the trailing digit matches the recomputed expected_check_digit, and always includes payload (the first eleven characters), converted, check_digit, expected_check_digit, and length twelve. Alias keys such as isin, number, and text are accepted for the same payload field so integrations that already speak “isin” do not need a rename. Because the path is pure parse with no clock, random source, or network, the same JSON body always yields the same JSON result on the free browser tool and on the API at $0.002 per successful request.
Where ISIN check digits fit real workflows
Middle-office and static-data teams recompute expected_check_digit when a counterparty reads a code over the phone or pastes it from a PDF, catching mistypes before a trade is booked against the wrong security.
Integration use cases
Complete an 11-character body for master data
Call compute mode with the eleven-character country+NSIN body, store with_check, and publish the twelve-character ISIN in instrument master, prospectuses, or corporate-action notices.
Validate typed or imported ISINs at entry
When a form, FIX feed, or partner file submits twelve characters, call validate mode and block booking when valid is false, showing expected_check_digit to help correct a single mistype.
Technical questions
How do I compute an ISIN check digit with this API?
POST with code set to exactly eleven alphanumeric characters (two-letter country code plus nine-character NSIN) and mode compute (or omit mode). The response includes check_digit and with_check (the full twelve-character ISIN).
How do I validate a full twelve-character ISIN?
POST with the twelve-character string and mode validate. The response includes valid, check_digit, expected_check_digit, payload (characters without the last one), and converted (the expanded digit string).
What happens with wrong length, hyphens, or a letter check digit?
Non-alphanumeric input, lengths other than eleven (compute) or twelve (validate), a non-digit twelfth character, and bodies that are not two letters plus nine alnum are rejected with invalid_input. Failed validation tasks are not billed.