How to Validate CUSIP and ISIN Security Identifiers
Every security traded on US and international markets has a unique identifier. In the United States, that identifier is a CUSIP (Committee on Uniform Securities Identification Procedures). Internationally, it is an ISIN (International Securities Identification Number). Both include a check digit that can be validated algorithmically -- no database lookup required.
If you are building a trading platform, portfolio tracker, reconciliation system, or any application that handles security identifiers, validating these numbers at the point of entry catches data errors before they propagate through your system.
What is a CUSIP
A CUSIP is a 9-character identifier assigned to securities traded in the United States and Canada. It has three parts:
- Characters 1-6: Issuer code (identifies the company or entity)
- Characters 7-8: Issue number (identifies the specific security from that issuer)
- Character 9: Check digit
Characters can be digits (0-9) or uppercase letters (A-Z). Letters are converted to numbers for checksum calculation: A=10, B=11, ..., Z=35.
Apple's common stock CUSIP is 037833100:
-
037833= Apple Inc. (issuer) -
10= Common stock (issue) -
0= Check digit
The CUSIP checksum algorithm
The CUSIP check digit uses a modified Luhn algorithm. Here is how it works:
- Take the first 8 characters of the CUSIP
- Convert letters to numbers (A=10, B=11, ..., Z=35)
- For characters in even positions (0-indexed), multiply the value by 2
- If the result is two digits, add them together (e.g., 14 becomes 1+4=5)
- Sum all values
- The check digit is
(10 - (sum % 10)) % 10
const validateCusip = (cusip) => {
if (cusip.length !== 9) { return false; }
const charValue = (c) => {
if (c >= '0' && c <= '9') { return parseInt(c, 10); }
return c.charCodeAt(0) - 55; // A=10, B=11, ..., Z=35
};
let sum = 0;
for (let i = 0; i < 8; i++) {
let val = charValue(cusip[i].toUpperCase());
if (i % 2 === 1) { val *= 2; }
sum += Math.floor(val / 10) + (val % 10);
}
const checkDigit = (10 - (sum % 10)) % 10;
return checkDigit === parseInt(cusip[8], 10);
};
validateCusip('037833100'); // true (Apple)
validateCusip('594918104'); // true (Microsoft)
validateCusip('037833109'); // false (wrong check digit)
Let us walk through Apple's CUSIP 037833100:
Position: 0 1 2 3 4 5 6 7
Char: 0 3 7 8 3 3 1 0
Value: 0 3 7 8 3 3 1 0
Even pos: 0 7 3 1
Odd pos: 6 16 6 0 (doubled)
Digit sum: 0 6 7 7 3 6 1 0 = 30
Check: (10 - 30%10) % 10 = 0
The calculated check digit is 0, matching the 9th character. The CUSIP is valid.
What is an ISIN
An ISIN is a 12-character identifier used internationally. It wraps a CUSIP (or other national identifier) with a country code and its own check digit:
- Characters 1-2: ISO 3166-1 country code (e.g., US, GB, JP)
- Characters 3-11: National security identifier (CUSIP for US securities)
- Character 12: Check digit
Apple's ISIN is US0378331005:
-
US= United States -
037833100= Apple's CUSIP -
5= ISIN check digit
Notice the ISIN check digit (5) is different from the CUSIP check digit (0). They use different algorithms.
The ISIN checksum algorithm
The ISIN check digit uses the standard Luhn algorithm, but first converts the entire identifier (including letters) to a numeric string:
- Take the first 11 characters
- Convert all letters to numbers (A=10, B=11, ..., Z=35)
- Concatenate into a single numeric string
- Apply the Luhn algorithm to this numeric string
- The check digit is
(10 - (sum % 10)) % 10
const validateIsin = (isin) => {
if (isin.length !== 12) { return false; }
if (!/^[A-Z]{2}[A-Z0-9]{9}[0-9]$/.test(isin)) { return false; }
// Convert to numeric string
const numericStr = isin.slice(0, 11).split('').map((c) => {
if (c >= '0' && c <= '9') { return c; }
return (c.charCodeAt(0) - 55).toString();
}).join('');
// Luhn algorithm on numeric string
let sum = 0;
const digits = numericStr.split('').map(Number).reverse();
digits.forEach((d, i) => {
let val = i % 2 === 0 ? d * 2 : d;
if (val > 9) { val -= 9; }
sum += val;
});
const checkDigit = (10 - (sum % 10)) % 10;
return checkDigit === parseInt(isin[11], 10);
};
validateIsin('US0378331005'); // true (Apple)
validateIsin('US5949181045'); // true (Microsoft)
validateIsin('US0378331009'); // false (wrong check digit)
Parsing components
Beyond validation, parsing a CUSIP or ISIN into its components is useful for display and classification:
{
"cusip": "037833100",
"valid": true,
"issuerCode": "037833",
"issueNumber": "10",
"checkDigit": "0",
"securityType": "equity"
}
{
"isin": "US0378331005",
"valid": true,
"countryCode": "US",
"country": "United States",
"nationalId": "037833100",
"nationalIdType": "CUSIP",
"checkDigit": "5"
}
The issue number in a CUSIP gives hints about the security type. Issue numbers 10-19 typically indicate common stock, 20-29 indicate preferred stock, and 40-49 indicate corporate bonds.
Using the MCP server
The @easysolutions906/mcp-cusip-isin MCP server provides cusip_validate, isin_validate, cusip_parse, and isin_parse tools. Add it to Claude Desktop or Cursor:
{
"mcpServers": {
"cusip-isin": {
"command": "npx",
"args": ["-y", "@easysolutions906/mcp-cusip-isin"]
}
}
}
Then ask questions like:
- "Is CUSIP 037833100 valid?"
- "Validate ISIN US0378331005"
- "Parse this CUSIP into its components: 594918104"
- "What country is ISIN GB0002634946 from?"
Where validation matters
Trade order entry. Validate the CUSIP or ISIN before submitting an order. A single transposed digit routes the trade to the wrong security.
Portfolio reconciliation. When reconciling positions between systems, validate every identifier first. Invalid identifiers indicate data corruption or mapping errors.
Regulatory reporting. SEC and FINRA filings require valid CUSIPs. Submitting an invalid identifier triggers a rejection.
Data import. When importing security master data from external sources (Bloomberg, Refinitiv, custodian feeds), validate every CUSIP and ISIN on import. Bad data in the security master propagates to every downstream calculation.
CUSIP and ISIN validation is pure algorithm -- no dataset, no API call, no external dependency. The @easysolutions906/mcp-cusip-isin npm package makes it available as both an MCP tool for AI assistants and a programmatic utility for trading applications.
Top comments (0)