VALOR Validation in Node.js
The Valorennummer is Switzerland's native securities identifier — 5 to 9 digits, no check digit, purely numeric, and embedded in every Swiss and Liechtenstein ISIN. Here's how to validate VALORs correctly in Node.js and enrich them with live instrument data.
In this guide
1. What is a VALOR?
A VALOR (Valorennummer — also written Valoren number or simply Valor) is a numeric identifier assigned to securities traded in Switzerland and Liechtenstein. It is issued by SIX Financial Information (part of the SIX Group, Zurich), which acts as the National Numbering Agency (NNA) for Switzerland under ISO 6166.
VALORs appear in Swiss brokerage confirmations, bank statements, and financial data feeds from SIX. While ISINs have become the standard for cross-border and regulatory contexts, VALORs remain widely used in Swiss private banking, asset management, and fund administration. Many Swiss financial APIs expose VALORs as the primary identifier alongside ISINs.
Unlike WKN (Germany) or CUSIP (USA), the VALOR is purely numeric — it contains only digits, never letters. Like WKN and unlike ISIN or SEDOL, the VALOR has no check digit. There is no algorithm to verify whether a VALOR is valid — the only way to confirm it maps to a real security is to look it up in a reference database.
2. VALOR anatomy
A VALOR is between 5 and 9 digits long, containing only decimal digits:
| Property | Detail |
|---|---|
| Length | 5–9 digits |
| Allowed characters | [0-9] only |
| Check digit | None |
| Issuing authority | SIX Financial Information (SIX Group), Zurich |
| Scope | Swiss and Liechtenstein securities (equities, bonds, funds, structured products) |
| OpenFIGI idType | ID_VALOR |
Some well-known examples:
| VALOR | ISIN | Security |
|---|---|---|
| 1213853 | CH0012138530 | UBS Group AG |
| 1222171 | CH0012221716 | ABB Ltd |
| 1200526 | CH0012005267 | Novartis AG |
| 3886335 | CH0038863350 | Nestlé SA |
3. VALOR inside a Swiss ISIN
Swiss ISINs (country code CH) and Liechtenstein ISINs (country code LI) embed the VALOR in a predictable way. The NSIN (National Securities Identifying Number) portion is the VALOR zero-padded on the left to 9 characters:
| Part | Chars | Example |
|---|---|---|
| Country code | 1–2 | CH |
| NSIN (VALOR padded to 9) | 3–11 | 001213853 |
| ISIN check digit | 12 | 0 |
For UBS Group AG (VALOR 1213853):
CH + 001213853 + 0 = CH0012138530 ┌──┐ ┌──┐┌───────┐ ┌┐ │CH│ │00││1213853│ │0│ ← ISIN check digit (Luhn over expanded string) └──┘ └──┘└───────┘ └┘ ↑ ↑ country VALOR zero-padded to 9 chars
To build the ISIN from a VALOR in Node.js:
function valorToNsin(valor) { return valor.padStart(9, '0'); } // The ISIN check digit uses the standard Luhn algorithm on // the alphanumeric expansion of "CH" + NSIN. Use /v0/isin // to validate the full ISIN rather than computing it manually. const valor = '1213853'; const nsin = valorToNsin(valor); // → '001213853' // ISIN = 'CH' + nsin + isinCheckDigit
You can extract a VALOR from a Swiss ISIN by taking characters 3–11 (1-indexed) and stripping the leading zeros. If you already have a CH or LI ISIN, pass it to /v0/isin instead of /v0/valor.
4. Why format checks aren't enough
No check digit — any 5–9 digit string passes format validation
Because VALOR has no check digit, every 5-to-9-digit string is structurally valid. A typo like 1213854 instead of 1213853 passes a regex check but refers to a completely different security — or no security at all. Without a database lookup, there is no way to detect the error.
Variable length — 5 to 9 digits
VALORs are not a fixed length. Early securities have shorter VALORs (starting from 5 digits); newer issuances have longer ones (up to 9 digits). Systems that assume a fixed length will fail silently on valid short VALORs or reject valid long ones.
Retired and superseded VALORs
When a company is acquired, merged, or delisted, its VALOR may be retired. A structurally valid VALOR might map to a company that no longer exists or a fund that was wound up. Format validation cannot distinguish an active security from a retired one.
Leading zeros in legacy systems
Some systems store or transmit VALORs zero-padded to a fixed length (e.g. 9 digits to match the NSIN). The API normalises this automatically: leading zeros are stripped as long as the result still has at least 5 digits. If your data source passes VALORs in inconsistent formats, the API handles it for you.
5. The right solution: one API call
The IsValid VALOR API handles format validation and instrument lookup via OpenFIGI in a single GET /v0/valor request. Because there is no check digit to compute, the value is entirely in the enrichment: confirming the VALOR maps to a real security and surfacing its name, ISIN, exchange, and FIGI.
Get your free API key at isvalid.dev. The free tier includes 100 calls per day.
Full parameter reference and response schema: VALOR Validation API docs →
6. Node.js code example
Using the @isvalid-dev/sdk package or the native fetch API (Node 18+).
// valorValidator.js import { createClient } from '@isvalid-dev/sdk'; const iv = createClient({ apiKey: process.env.ISVALID_API_KEY }); // ── Example usage ───────────────────────────────────────────────────────────── const result = await iv.valor('1213853'); // UBS Group AG if (!result.valid) { console.log('Invalid VALOR: must be 5–9 digits (no letters)'); } else { console.log(`VALOR : ${result.valor}`); if (result.found) { console.log(`Name : ${result.name}`); console.log(`ISIN : ${result.isin}`); console.log(`Ticker : ${result.ticker}`); console.log(`Exchange : ${result.exchCode}`); console.log(`FIGI : ${result.figi}`); console.log(`Sector : ${result.marketSector}`); } }
Expected output for 1213853:
VALOR : 1213853 Name : UBS Group AG ISIN : CH0012138530 Ticker : UBSG Exchange : SE FIGI : BBG000BVD464 Sector : Equity
In an Express.js route handler:
// routes/securities.js (Express) app.get('/securities/validate-valor', async (req, res) => { const { valor } = req.query; if (!valor) { return res.status(400).json({ error: 'Missing valor parameter' }); } let result; try { result = await validateValor(valor); } catch { return res.status(502).json({ error: 'VALOR validation service unavailable' }); } if (!result.valid) { return res.status(400).json({ error: 'Invalid VALOR', valor }); } res.json({ valor: result.valor, found: result.found ?? null, isin: result.isin ?? null, name: result.name ?? null, ticker: result.ticker ?? null, exchCode: result.exchCode ?? null, figi: result.figi ?? null, }); });
001213853 and 1213853 are handled correctly.7. cURL example
UBS Group AG:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/valor?value=1213853"
Nestlé SA:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/valor?value=3886335"
Invalid format — fewer than 5 digits:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/valor?value=1234"
8. Understanding the response
Response for a valid VALOR found in OpenFIGI:
{ "valid": true, "valor": "1213853", "found": true, "dataSource": "openfigi", "isin": "CH0012138530", "name": "UBS Group AG", "ticker": "UBSG", "exchCode": "SE", "securityType": "Common Stock", "marketSector": "Equity", "figi": "BBG000BVD464", "compositeFIGI": "BBG000BVD464" }
Response for a valid VALOR not found in OpenFIGI:
{ "valid": true, "valor": "1213853", "found": false }
Response for an invalid VALOR:
{ "valid": false }
| Field | Type | Description |
|---|---|---|
| valid | boolean | Format validation result (5–9 digits) |
| valor | string | Normalised (whitespace-stripped, leading-zeros-removed) VALOR |
| found | boolean | null | true — found in OpenFIGI; false — not found; null — OpenFIGI unavailable |
| dataSource | string | Always openfigi when present |
| isin | string | null | Associated ISIN (e.g. CH0012138530); null if not returned |
| name | string | null | Full instrument name |
| ticker | string | null | Exchange ticker symbol |
| exchCode | string | null | Bloomberg exchange code (e.g. SE for SIX Swiss Exchange) |
| securityType | string | null | Security type (e.g. Common Stock) |
| marketSector | string | null | Market sector (e.g. Equity) |
| figi | string | null | Financial Instrument Global Identifier |
| compositeFIGI | string | null | Composite FIGI across all exchanges |
9. Edge cases to handle
found: null vs. found: false
found: false means OpenFIGI was reachable but did not recognise the VALOR. found: null means the lookup failed (timeout, rate limit, or network error). In the null case the VALOR is still structurally valid — treat it as inconclusive and retry rather than rejecting it.
VALOR vs. ISIN — know which you have
If you receive a 12-character code starting with CH or LI, it is a Swiss or Liechtenstein ISIN — use /v0/isin instead. A 5–9 digit code is a VALOR; use /v0/valor. You can extract the VALOR from a CH or LI ISIN by taking characters 3–11 and stripping leading zeros.
Multiple listings per VALOR
OpenFIGI may return a result for the primary listing on SIX Swiss Exchange (exchange code SE). The same security may also trade on other exchanges, as ADRs, or in other currencies. The API returns the first matching result; use the ISIN from the response to look up all listings via /v0/isin if you need the complete picture.
10. Summary
| What | Detail |
|---|---|
| Format | 5–9 digits only [0-9], no letters, no check digit |
| Check algorithm | None — purely opaque numeric sequence |
| Issuing authority | SIX Financial Information (SIX Group), Zurich |
| Coverage | Swiss and Liechtenstein securities (equities, bonds, funds, structured products) |
| Enrichment source | OpenFIGI (Bloomberg) via ID_VALOR |
| API endpoint | GET /v0/valor?value=1213853 |
For cross-referencing, see also:
- ISIN validation — ISINs embed VALORs for CH/LI-prefixed codes
- WKN validation — the German equivalent (alphanumeric)
- SEDOL validation — the UK equivalent
- CUSIP validation — the North American equivalent
- VALOR Validation in Python
Node.js integration notes
In a TypeScript codebase, define a branded type to prevent VALORs from being confused with other numeric strings at compile time: type Valor = string & { readonly __brand: 'Valor' }. Validate at the system boundary — when the VALOR enters your application from user input, an upstream API, or a file import — and carry the branded type through the rest of your pipeline.
VALOR validation is particularly relevant in Swiss private banking and asset management integrations: order entry systems, portfolio management dashboards, and fund administration tools. If your application accepts VALORs from users, the absence of a check digit means any plausible-looking numeric string passes format validation. Pair the API call with client-side pattern matching (/^\d{5,9}$/) for instant UI feedback, and confirm against OpenFIGI on submission.
Caching strategy
VALOR-to-instrument mappings change infrequently — corporate actions aside, a given VALOR refers to the same security for years. Cache validated results in Redis with a 24-hour TTL using the normalised VALOR as the key. The IsValid API already caches OpenFIGI responses for 24 hours on its end; your own cache layer eliminates the network round trip for repeated lookups of the same identifier within a session.
- Assert
process.env.ISVALID_API_KEYat server startup, not lazily at first request - Use
Promise.allSettled()for batch VALOR validation — it collects all results without aborting on the first failure - Log the full parsed API response alongside the raw VALOR — the ISIN and FIGI returned are useful for downstream reconciliation
- If you need the full ISIN from a VALOR, use the
isinfield from the response rather than constructing it manually