Guide · Node.js · SDK · REST API

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.

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:

PropertyDetail
Length5–9 digits
Allowed characters[0-9] only
Check digitNone
Issuing authoritySIX Financial Information (SIX Group), Zurich
ScopeSwiss and Liechtenstein securities (equities, bonds, funds, structured products)
OpenFIGI idTypeID_VALOR

Some well-known examples:

VALORISINSecurity
1213853CH0012138530UBS Group AG
1222171CH0012221716ABB Ltd
1200526CH0012005267Novartis AG
3886335CH0038863350Nestlé SA
ℹ️Unlike WKN (Germany), which can contain letters A–Z, a VALOR is always purely numeric. If you see an identifier containing letters, it is not a VALOR — it may be a WKN or another national identifier.

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:

PartCharsExample
Country code1–2CH
NSIN (VALOR padded to 9)3–11001213853
ISIN check digit120

For UBS Group AG (VALOR 1213853):

CH  +  001213853  +  0  =  CH0012138530
      
CH   001213853   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.

Format
Validation
5–9 digit numeric check
Live
Enrichment
Name, ISIN, FIGI, exchange & more
100/day
Free tier
no credit card

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,
  });
});
The API strips whitespace and leading zeros automatically — pass the raw value without pre-processing. Both 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
}
FieldTypeDescription
validbooleanFormat validation result (5–9 digits)
valorstringNormalised (whitespace-stripped, leading-zeros-removed) VALOR
foundboolean | nulltrue — found in OpenFIGI; false — not found; null — OpenFIGI unavailable
dataSourcestringAlways openfigi when present
isinstring | nullAssociated ISIN (e.g. CH0012138530); null if not returned
namestring | nullFull instrument name
tickerstring | nullExchange ticker symbol
exchCodestring | nullBloomberg exchange code (e.g. SE for SIX Swiss Exchange)
securityTypestring | nullSecurity type (e.g. Common Stock)
marketSectorstring | nullMarket sector (e.g. Equity)
figistring | nullFinancial Instrument Global Identifier
compositeFIGIstring | nullComposite 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

WhatDetail
Format5–9 digits only [0-9], no letters, no check digit
Check algorithmNone — purely opaque numeric sequence
Issuing authoritySIX Financial Information (SIX Group), Zurich
CoverageSwiss and Liechtenstein securities (equities, bonds, funds, structured products)
Enrichment sourceOpenFIGI (Bloomberg) via ID_VALOR
API endpointGET /v0/valor?value=1213853

For cross-referencing, see also:


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_KEY at 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 isin field from the response rather than constructing it manually