ISINIdentifiersFundamentals

What is an ISIN? A developer's guide to fund and ETF identifiers

ISIN format, check digit, how it differs from tickers, SEDOL, CUSIP and WKN, and how to validate an ISIN in code before you look up fund data.Published 12 August 2026 · 3 min read · by FundFacts API

If you work with investment funds, you will meet the ISIN before anything else. It is printed on factsheets, KIDs, order confirmations and custody statements, and it is the key that almost every fund data API — including FundFacts API — accepts as input. This guide explains what an ISIN is, how it is built, how it compares with other identifiers and how to validate one in code.

The short definition

An ISIN (International Securities Identification Number) is a 12-character code that uniquely identifies a security worldwide. It is defined by ISO 6166 and issued by each country's National Numbering Agency. Every share class of every fund has its own ISIN, which is exactly why it is the right key for fund data: IE00B4L5Y983 means one specific share class of one specific ETF, not "the MSCI World ETF" in general.

Anatomy of an ISIN

PositionMeaningExample (IE00B4L5Y983)
1–2ISO 3166 country code of the issuing agencyIE (Ireland)
3–11National Securities Identifying Number (NSIN), padded with zeros00B4L5Y98
12Check digit (Luhn algorithm)3

A few practical consequences:

  • The country prefix tells you where the fund is domiciled, not where it is sold. Irish (IE) and Luxembourg (LU) prefixes dominate UCITS funds distributed across Europe.
  • The middle part often embeds a national code. For UK and Irish securities it is the SEDOL; for US securities it is the CUSIP. That is why US ISINs look like US + 9-digit CUSIP + check digit.
  • Letters are allowed anywhere in positions 3–11, so never store ISINs as numbers.

ISIN vs ticker, SEDOL, CUSIP, WKN

IdentifierScopeUnique per share class?Typical use
ISINGlobalYesFund data, settlement, regulatory reporting
TickerPer exchangeNo — the same ETF has different tickers on Xetra, LSE and Borsa ItalianaTrading screens
SEDOLUK / IrelandYesUK custody and settlement
CUSIPUS / CanadaYesNorth American markets
WKNGermanyYesGerman retail platforms

Tickers are the trap. IWDA on the London Stock Exchange, EUNL on Xetra and SWDA on Borsa Italiana are all the same share class — the ISIN is what unifies them. If your users type tickers, map them to ISINs first; if they type ISINs, you are already done.

Validating an ISIN in code

Before you spend a request on a lookup, check the format and the check digit. The check digit uses the Luhn algorithm applied to the digit expansion of the code (A=10, B=11 … Z=35).

javascript
const ISIN_RE = /^[A-Z]{2}[A-Z0-9]{9}\d$/;
export function isValidIsin(raw) {
const isin = String(raw ?? "").trim().toUpperCase();
if (!ISIN_RE.test(isin)) return false;
let digits = "";
for (const ch of isin) {
const code = ch.charCodeAt(0);
digits += code >= 65 ? String(code - 55) : ch; // A -> 10 ... Z -> 35
}
let sum = 0;
let double = false;
for (let i = digits.length - 1; i >= 0; i--) {
let d = Number(digits[i]);
if (double) { d *= 2; if (d > 9) d -= 9; }
sum += d;
double = !double;
}
return sum % 10 === 0;
}
isValidIsin("IE00B4L5Y983"); // true
isValidIsin("IE00B4L5Y984"); // false — bad check digit

The same logic in Python:

python
import re
ISIN_RE = re.compile(r"^[A-Z]{2}[A-Z0-9]{9}\d$")
def is_valid_isin(raw: str) -> bool:
isin = (raw or "").strip().upper()
if not ISIN_RE.match(isin):
return False
digits = "".join(str(ord(c) - 55) if c.isalpha() else c for c in isin)
total, double = 0, False
for ch in reversed(digits):
d = int(ch)
if double:
d = d * 2
if d > 9:
d -= 9
total += d
double = not double
return total % 10 == 0
Tip
FundFacts API runs exactly this validation server-side and returns 400 invalid_isin for malformed codes, so a typo never counts against your quota. Validating client-side just saves a round trip.

Common gotchas

  • Lower case and whitespace. Users paste ISINs from PDFs with stray spaces. Normalise with trim().toUpperCase().
  • Confusing 0 and O. O is a valid character in positions 3–11; the check digit will usually catch a swap, but not always. Show the parsed ISIN back to the user.
  • Share classes. A fund family can have dozens of ISINs (accumulating vs distributing, hedged vs unhedged, retail vs institutional). Ask for the ISIN, not the fund name.
  • Reused codes. ISINs are not recycled, but a fund can be liquidated. A valid ISIN does not guarantee a live product — your data layer should return a clean 404 in that case.

From ISIN to data

Once you have a valid ISIN, a single request returns the structured factsheet:

bash
curl https://fundfactsapi.com/api/v1/funds/IE00B4L5Y983 \
-H "Authorization: Bearer ffk_your_key"

The response contains key facts, holdings, exposures, risk metrics and performance in one JSON schema. See how to get fund data from an ISIN for a full walkthrough, or create a free key and try your own ISIN.

Try it on your own ISINs

One request returns key facts, holdings, risk and performance as JSON. Free plan, no card.