← Blog

IBAN Validation API: Checksum, Country Rules and BIC Lookup in One Call

#fintech#api#payments#javascript

Every payments, payroll or invoicing product eventually adds an IBAN field, and then a support ticket arrives: "The transfer bounced, the IBAN was wrong." A good IBAN check at input time catches most of these before they cost you a failed SEPA payment and a confused customer.

Here's what a proper IBAN validation involves, and how to get it from one API call.

Anatomy of an IBAN

Take DE89 3704 0044 0532 0130 00:

Part Value Meaning
Country code DE ISO 3166 country
Check digits 89 mod-97 checksum over the whole IBAN
BBAN 370400440532013000 The national account number (Basic Bank Account Number)
Bank code 37040044 German Bankleitzahl, here Commerzbank in Cologne
Account 0532013000 The account itself

The BBAN's structure is different in every country. Germany is 8 digits bank code + 10 digits account (22 characters total). France is 27 characters with a 5-digit bank code, 5-digit branch, 11 alphanumeric account characters and a 2-digit national key. Malta is 31 characters. There are around 80 IBAN countries, each with its own rules.

The four checks that matter

1. Characters and country. Strip spaces, uppercase, check it starts with a real IBAN country code.

2. Length. Each country has exactly one valid length. DE with 21 characters is wrong, full stop.

3. Structure. The SWIFT IBAN registry defines the BBAN pattern, like 8!n10!n for Germany (8 digits, then 10 digits). Letters where digits should be means it's invalid.

4. mod-97 checksum. Move the first four characters to the end, replace letters with numbers (A=10 ... Z=35), and the remainder modulo 97 must be 1:

function mod97(iban) {
  const s = iban.slice(4) + iban.slice(0, 4);
  let rem = 0;
  for (const ch of s) {
    const v = /[A-Z]/.test(ch) ? String(ch.charCodeAt(0) - 55) : ch;
    for (const d of v) rem = (rem * 10 + Number(d)) % 97;
  }
  return rem === 1;
}

This catches all single-character typos and almost all transpositions, which are the most common data-entry errors.

What a checksum can't tell you: whether the account actually exists or is open. Only the bank (or a paid account verification service) knows that. Be wary of any API that claims otherwise from the IBAN alone.

The useful extra: bank name and BIC

Users like seeing "Commerzbank" appear under the field; it reassures them they typed the right thing. And many older payment integrations still need a BIC.

Once you know where the bank code sits in the BBAN, you can look it up in national bank directories. Central banks and payment associations publish these, for example the Deutsche Bundesbank's Bankleitzahlen file, the Austrian OeNB directory, Belgium's NBB list and the Dutch Betaalvereniging BIC list.

Keeping a dozen national files up to date is a chore, so we bundle them.

One API call

The VAT & IBAN Validation API does all of the above offline, so it is fast and never depends on an external service being up:

curl -X POST https://vatpulse1.p.rapidapi.com/validate \
  -H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
  -H "X-RapidAPI-Host: vatpulse1.p.rapidapi.com" \
  -H "Content-Type: application/json" \
  -d '{"iban": "DE89 3704 0044 0532 0130 00"}'
{
  "iban": {
    "valid": true,
    "iban": "DE89370400440532013000",
    "iban_formatted": "DE89 3704 0044 0532 0130 00",
    "country_code": "DE",
    "check_digits": "89",
    "bban": "370400440532013000",
    "bank_code": "37040044",
    "account_number": "0532013000",
    "sepa": true,
    "bank": { "name": "Commerzbank Köln", "bic": "COBADEFFXXX" },
    "source": "offline",
    "cached": false,
    "error": null
  },
  "billable": true
}

A typo produces a precise error instead of a generic "invalid":

{ "iban": { "valid": false, "error": { "code": "invalid_checksum", "message": "The IBAN check digits are wrong (mod-97 checksum failed). Likely a typo." } } }

Possible codes: invalid_format, invalid_country, invalid_length, invalid_checksum. That lets you show helpful messages ("German IBANs are 22 characters, you entered 21").

Bank/BIC coverage

Checksum, length and structure work for every IBAN country. Bank name/BIC lookup comes from openly published national registries and covers countries including Germany, Austria, Belgium, the Netherlands, Spain, Italy, Switzerland, Poland, Nordic and Baltic countries and others; for France, the UK, Ireland and Portugal it covers the major banks. When a bank code isn't in our dataset, bank is simply null; the IBAN is still fully validated. The docs list exact coverage.

Validate VAT and IBAN together

Onboarding a B2B customer? Send both in one request; it counts as one validation:

{ "vat": "IE6388047V", "iban": "IE29AIBK93115212345678" }

Pricing that doesn't punish retries

You pay only for fresh successful checks. Repeat lookups of the same IBAN within 24 hours are cache hits and free, and malformed input rejected before the checksum is free too.

Get a free key on RapidAPI · Read the docs

Try it free

100 validations/month. Get a free key on RapidAPI · Docs