Validating bank details in your application prevents failed payments, reduces support tickets, and gives users immediate feedback when they enter incorrect account numbers. Whether you are building a checkout flow, a payroll system, or a payment integration, catching invalid IBANs, routing numbers, and sort codes at the point of entry saves time and money for everyone involved. This guide walks through the BankCheck free API, validation algorithms, error handling best practices, and testing strategies. For the full API reference, see our API documentation.
Manual verification of bank details does not scale. When a user enters an IBAN, routing number, or sort code into your application, you need to verify it programmatically before submitting a payment. Here is why this matters:
BankCheck provides a free validation API that requires no signup, no API key, and no authentication. CORS is enabled for all origins, making it usable directly from browser-based applications. The API validates IBANs, US routing numbers, UK sort codes, and SWIFT/BIC codes.
The endpoint accepts both GET and POST requests:
/api/v1/validate?q=DE89370400440532013000/api/v1/validate with JSON body { "input": "DE89370400440532013000" }The API auto-detects the format (IBAN, routing number, sort code, or SWIFT/BIC) from the input. You can also pass an optional format parameter to skip auto-detection. See the full API documentation for response schemas and all supported parameters.
Below are working examples for the three most common integration patterns. Each validates a German IBAN and shows the expected request and response structure.
curl
curl -X POST https://bankcheck.io/api/v1/validate -H "Content-Type: application/json" -d '{ "input": "DE89370400440532013000" }'
The response includes apiVersion, processingTimeMs, and a result object containing validation status, detected format, breakdown, and any errors.
JavaScript (fetch)
const response = await fetch("/api/v1/validate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ input: "DE89370400440532013000" }) });
const data = await response.json();
const isValid = data.result.isValid; // true
The response JSON includes the detected format, a detailed breakdown of the IBAN components, and the validation result.
Python (requests)
resp = requests.post("https://bankcheck.io/api/v1/validate", json={"input": "DE89370400440532013000"})
data = resp.json()
is_valid = data["result"]["isValid"] # True
The response structure is identical regardless of the client language.
It is important to understand the distinction between validation and verification when working with bank details. These are two different operations with different guarantees.
| Aspect | Validation | Verification |
|---|---|---|
| What it checks | Format, length, checksum, country rules | Account exists and is active at the bank |
| How it works | Algorithmic (no network call needed) | Requires querying the bank's systems |
| Speed | Instant (sub-millisecond) | Seconds to days |
| Guarantee | Number is structurally correct | Account is real and reachable |
BankCheck performs validation. It checks that the bank number conforms to the correct format, passes the relevant checksum algorithm, and matches the expected structure for its country. It does not contact the bank to confirm the account exists. Validation catches the vast majority of user-entry errors (typos, transposed digits, wrong length) but cannot guarantee the payment will succeed.
The IBAN checksum uses the MOD-97 algorithm defined in ISO 13616. Below is a pseudocode walkthrough of how it works. This is for educational purposes — for production use, call the BankCheck API or use a well-tested library. For a deeper explanation, see our guide on the IBAN validation algorithm.
Step 1: Rearrange the IBAN
Move the first 4 characters (country code + check digits) to the end of the string. For GB29NWBK60161331926819, this becomes NWBK60161331926819GB29.
Step 2: Convert letters to numbers
Replace each letter with its position in the alphabet plus 9. A becomes 10, B becomes 11, and so on up to Z which becomes 35. The rearranged string becomes a very large integer. For example, N = 23, W = 32, B = 11, K = 20, G = 16, B = 11.
Step 3: Compute MOD-97 using chunked arithmetic
The resulting number is too large for standard integer types. Instead, process it in chunks: take the first 9 digits, compute the remainder when divided by 97, prepend that remainder to the next chunk, and repeat until the entire number is processed.
In pseudocode:
remainder = 0
for each chunk of 7 digits from the numeric string:
remainder = (remainder + chunk) mod 97
Step 4: Check the result
If the final remainder is 1, the IBAN is valid. Any other result means the IBAN contains an error. This single check catches over 99.97% of transcription errors, including transposed digits and single-character substitutions.
US routing numbers use a weighted checksum algorithm based on the digits' positions. The algorithm multiplies each of the 9 digits by a weight from the repeating pattern 3, 7, 1, then checks whether the sum is divisible by 10.
Given a routing number with digits d1 through d9, the formula is:
sum = 3*d1 + 7*d2 + 1*d3 + 3*d4 + 7*d5 + 1*d6 + 3*d7 + 7*d8 + 1*d9
If sum mod 10 === 0, the routing number passes the checksum. For example, routing number 021000021 (JPMorgan Chase):
3*0 + 7*2 + 1*1 + 3*0 + 7*0 + 1*0 + 3*0 + 7*2 + 1*1 = 0 + 14 + 1 + 0 + 0 + 0 + 0 + 14 + 1 = 30
30 mod 10 = 0, so the checksum passes. Like the IBAN MOD-97 algorithm, this check catches transposed and substituted digits but does not confirm the routing number is currently active at a bank.
Good validation is not just about returning true or false. The error messages you show users determine whether they can fix the problem themselves or need to contact support. Generic messages like “Invalid IBAN” are unhelpful. Specific messages like “IBAN is 2 characters too short for a German account” tell the user exactly what to fix.
The BankCheck API returns structured error information when validation fails. The response includes an error code, a human-readable message, and the detected format:
Example error response
{ "apiVersion": "1", "result": { "isValid": false, "format": "iban", "errors": [{ "code": "INVALID_LENGTH", "message": "German IBANs must be 22 characters, got 20" }] } }
When building your own validation layer, follow the same principle. Return the specific problem (wrong length, invalid checksum, unknown country code) along with enough context for the user to correct it. If the IBAN is too short, tell them by how many characters. If the country code is unrecognized, suggest they check the first two letters.
A robust validation implementation requires thorough testing across formats, countries, and edge cases. Here are the strategies that matter most:
/api/v1/validate endpoint. The API auto-detects the format. You can also pass "format": "uk-sort-code" explicitly to skip auto-detection. The response includes the bank name, branch, and validation status.The fastest way to get started is to make a single request and inspect the response. No signup required. Visit our API documentation for the complete reference, including response schemas for each format, error codes, and the full list of supported countries. You can also test validation interactively using our IBAN validator, routing number checker, or sort code lookup — each tool uses the same validation engine that powers the API.
Back to all guides.