← Docs

Bank API

Validate an IBAN. Bank names in 100 countries and territories.

Validate an IBAN and identify its bank when known. Send the original input in a JSON body. Check valid and issues; a missing BIC does not invalidate the number or prove an account exists.

Validate an IBAN

POST
api.parseapi.com/bank
JSON body: iban, optional country and deep
Explore

Run uses the free demo on API 2.0.0. Copied code uses your API key when signed in, or YOUR_API_KEY when signed out.

import { parseAPI } from '@parseapi/sdk';

const parse = parseAPI("YOUR_API_KEY");
const result = await parse.bank("DE89370400440532013000");
// Handle result.valid and result.issues without logging account details.

Run on your server with a secret key. Calling from a browser or app?

Example response
{
  "iban": "DE89370400440532013000",
  "valid": true,
  "country": "DE",
  "formatted": "DE89 3704 0044 0532 0130 00",
  "bank": "37040044",
  "bank_name": "Commerzbank",
  "bic": "COBADEFFXXX",
  "checks": {
    "input": "passed",
    "country": "passed",
    "length": "passed",
    "structure": "passed",
    "checksum": "passed",
    "national": "not_supported"
  },
  "issues": []
}

Fixed public and synthetic examples are for integration testing, never payments. A checksum-valid synthetic value does not prove an account is unassigned.

Adding a field to your website? Set up an IBAN field with correction messages and bank-name fill. Keep account inputs out of your own logs, analytics and URLs, including response logging.

Validation rules and coverage

Structure and ISO checksum checks for 101 countries and territories, plus supported national BBAN checks. Matching directory records provide bank names in 100 countries and territories and BICs in 100. See the country coverage table.

Checksum an IBAN before you store it. You get the normalized number, the print form for display, the country and bank identifier, plus the bank name and BIC when each field has a matching directory record. That counts as a normal request. A string that is not an IBAN answers valid: false as a 200, never a 404.

bank is the code parsed from the number. bank_name and bic come from the national file. They are null when a match is missing or ambiguous. This does not prove the account exists. Pass ?country= when the value has no prefix. A prefix on the value wins. SEPA membership is a country fact: GET /bloc/sepa/countries lists the members.

National BBAN checks: BA, BE, BL, CZ, EE, ES, FR, GF, GP, HR, HU, IT, MC, ME, MF, MK, MQ, MR, NC, NO, PF, PL, PM, PT, RE, RS, SI, SK, SM, TF, WF, YT. Italy and San Marino include the CIN character. North Macedonia's additional check applies to numeric BBANs only. German and UK bank-specific checks and the Dutch domestic account check are not included. Use Parse-Version: 2.0.0 with Bank. API 1.0.0 keeps /iban/{iban} with ISO-only validity.

Send ASCII letters and digits, with optional Unicode whitespace or ASCII hyphens. Only those separators are removed and ASCII letters uppercased. Other punctuation, symbols and Unicode lookalikes fail the input check and remain visible in the echo. Send the original string as JSON; do not URL-encode it. Literal percent escapes are not decoded again.

checks reports input, country, length, structure, checksum and national checks in that order. A state is passed, failed, not_checked when an earlier prerequisite fails, or not_supported when no national check applies. An unsupported national check does not invalidate the IBAN. Clients should tolerate future states.

issues contains the first blocking finding, with a field, stable code and plain-text correction message. It is empty when applicable checks pass. These findings are independent of HTTP errors and directory matches. Current codes are required, invalid_characters, unsupported_country, invalid_length, invalid_structure, invalid_checksum and invalid_national_checksum.

Existing GET /bank/{iban} integrations remain supported on API 2.0.0. Prefer POST to keep account input out of the request URL. POST does not prevent applications or intermediaries from logging bodies.

Response fields

iban
ASCII letters uppercased, Unicode whitespace and ASCII hyphens removed. Invalid characters remain visible. null when empty
valid
Country length, BBAN structure, ISO MOD-97, and supported national BBAN checks. See the Bank reference for national-check scope
checks
Validation stages in order. States are open strings: passed, failed, not_checked or not_supported. Missing prerequisites remain not_checked
checks.input
Allowed input characters
checks.country
Recognized country prefix, optionally supplied by the country hint
checks.length
Country-specific IBAN length
checks.structure
Country-specific BBAN structure
checks.checksum
ISO MOD-97 check digits
checks.national
Supported national BBAN check. not_supported means no applicable check; it does not invalidate the IBAN
issues
First blocking finding, or an empty array when applicable checks pass. Independent of HTTP errors and directory coverage
issues[].field
Input to correct: iban or country. Open string
issues[].code
Stable issue code. Open string; see Bank reference for current codes
issues[].message
Plain-text correction advice
country
ISO 3166-1 alpha-2 from the prefix, or null when it is not an IBAN country
formatted
Print form in groups of four, for display. null when invalid
bank
Bank identifier parsed from the number, not a name. null when length is wrong
bank_name
Matching institution name from published bank-code sources. Independently null when unknown or ambiguous
bic
BIC from the same published sources. null when unsourced or missing

Country requirements

GET
api.parseapi.com/bank/requirements?country=DE
Country-specific input fields, supported checks and limitations
Explore
Parameters 2
countrystring · query · required

Two-letter country code.

formatstring · query · optional

Input format identifier.

Default: iban

Pass a two-letter country and optionally format (iban by default). The answer contains supported, fields, checks and limitations. An unsupported combination returns supported: false with no fields; this is not an account verdict. These are collection and validation requirements, not instructions to initiate a payment.

US ACH bank details

Check the supported account format and nine-digit routing checksum. This does not confirm account existence, ownership or ACH eligibility. The optional bank name comes from reference data, not a live ACH participation directory. Account checksum checking is not supported.

Account text is preserved exactly. Use ASCII letters, digits, spaces or hyphens with at least one letter or digit; at most 17 characters excluding spaces, including hyphens. These example values demonstrate format only and are not payment instructions.

import { parseAPI } from '@parseapi/sdk';

const parse = parseAPI('YOUR_API_KEY');
const result = await parse.bankUsAch({"routing":"021000021","account":"000123456789"});
// Handle result.valid and result.issues without logging account details.

Run on your server with a secret key. Calling from a browser or app?

Use GET /bank/requirements?country=US&format=us_ach for the field rules. Send format: "us_ach", country: "US", routing and account in the POST body. This format has no BIC or Deep option. issues identifies the routing or account field to correct; service failures are HTTP errors, not invalid details.

Test your integration

Download the named fixture kit and local mock server into one folder, then run node bank-mock.mjs. Send POST requests to http://127.0.0.1:8787/bank; it requires no key or network. The kit covers invalid characters, checksum and national failures, missing bank/BIC, exact branch scope, US ACH and an unavailable directory.

Use X-Bank-Fixture: directory_unavailable on the local mock to exercise an HTTP 503. The selector is only a mock feature. Never use fixture details for payments or treat a fixture response as a live directory observation. Normal website demos continue to call the live API.

Deep

"deep": true Checksum digits, branch/account decomposition and directory edition/match scope when a lookup ran. Included on every plan, with no additional charge.

Run uses the free demo on API 2.0.0. Copied code uses your API key when signed in, or YOUR_API_KEY when signed out.

import { parseAPI } from '@parseapi/sdk';

const parse = parseAPI("YOUR_API_KEY");
const result = await parse.bank("DE89370400440532013000", { deep: true });
// Handle result.valid and result.issues without logging account details.

Run on your server with a secret key. Calling from a browser or app?

Example response
{
  "iban": "DE89370400440532013000",
  "valid": true,
  "country": "DE",
  "formatted": "DE89 3704 0044 0532 0130 00",
  "bank": "37040044",
  "bank_name": "Commerzbank",
  "bic": "COBADEFFXXX",
  "checks": {
    "input": "passed",
    "country": "passed",
    "length": "passed",
    "structure": "passed",
    "checksum": "passed",
    "national": "not_supported"
  },
  "issues": [],
  "deep": {
    "checksum": "89",
    "branch": null,
    "account": "0532013000",
    "directory": {
      "edition": "b641e745a23e77e29fc3074931b9df864d3f57386ddd23268373a74d2c668f3b",
      "country": "DE",
      "match": "bank"
    }
  }
}

Deep fields

deep.checksum
The two check digits as a string, keeping a leading zero
deep.branch
Branch identifier when that country has one. null when it does not, or length is wrong
deep.account
The remaining BBAN after bank and branch, including national suffixes where present. Not a reconstructed domestic account
deep.directory
Directory evidence only when a lookup ran. Omitted otherwise; it does not identify why a field is null
deep.directory.edition
Edition fingerprint matching the downloadable coverage artifact
deep.directory.country
Directory country after resolving a territory alias
deep.directory.match
Whole-row match: bank, branch, prefix or none. No field borrowing across rows

Build with Bank

All tutorials →

Questions? Email