Skip to content
IBANforge

Recipes — validate an IBAN in your stack

Every recipe below does the same one call: POST /v1/iban/validate, which returns structure + checksum, the issuing bank (BIC), the bank-code check against the national register, EMI/vIBAN classification and SEPA/VoP reachability. Get a free key first (200 requests/month, no card):

curl -X POST https://api.ibanforge.com/v1/keys/generate \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com"}'

The honest note that belongs in every integration: a local mod-97 check catches typos and nothing else. Three of the four official example IBANs pass every checksum and still point at bank codes no register allocated — the full story. The register check is the part you cannot do locally.

Python

With the official SDK (pip install ibanforge):

from ibanforge import IBANforge
 
client = IBANforge(api_key="ifk_your_key")
result = client.validate("DE89370400440532013000")
print(result["valid"], result["bic"]["code"], result["bank_code_check"]["status"])
# True COBADEFFXXX verified

Or plain requests:

import requests
 
r = requests.post(
    "https://api.ibanforge.com/v1/iban/validate",
    json={"iban": "DE89370400440532013000"},
    headers={"Authorization": "Bearer ifk_your_key"},
    timeout=15,
)
data = r.json()
print(data["valid"], data["bank_code_check"]["status"])  # True verified

Node.js / TypeScript

Native fetch, no dependency:

const res = await fetch("https://api.ibanforge.com/v1/iban/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer ifk_your_key",
  },
  body: JSON.stringify({ iban: "DE89370400440532013000" }),
});
const data = await res.json();
console.log(data.valid, data.bic?.code, data.bank_code_check?.status);
// true COBADEFFXXX verified

The official SDK (npm install @ibanforge/sdk) wraps the same call with types.

PHP

No extension needed beyond what ships with PHP:

<?php
$payload = json_encode(["iban" => "DE89370400440532013000"]);
$ctx = stream_context_create(["http" => [
    "method"  => "POST",
    "header"  => "Content-Type: application/json\r\nAuthorization: Bearer ifk_your_key",
    "content" => $payload,
    "timeout" => 15,
]]);
$data = json_decode(file_get_contents(
    "https://api.ibanforge.com/v1/iban/validate", false, $ctx), true);
echo $data["valid"] ? "valid" : "invalid", " — ",
     $data["bank_code_check"]["status"] ?? "n/a", PHP_EOL;
// valid — verified

Java

The official Java SDK (Java 17+, Jackson only) mirrors the TypeScript client method for method. It is on Maven Central: depend on com.ibanforge:ibanforge-sdk:1.5.0.

IBANforge client = IBANforge.builder().apiKey(System.getenv("IBANFORGE_API_KEY")).build();
IBANValidationResult r = client.validateIban("DE89 3704 0044 0532 0130 00");
System.out.println(r.valid() + " " + r.bic().code() + " " + r.bankCodeCheck().status());

Errors are typed under IBANforgeException: PaymentRequiredException (402, the x402 challenge in accepts), RateLimitException, InvalidInputException, ApiException. client.formatIban(...) and the other free routes need no key. README and the full method table.

C# / .NET

The official .NET SDK (net8.0, no dependency beyond the framework) exposes the same methods as async calls. NuGet publication is pending; until then reference the project or dotnet pack it from sdks/dotnet (package id IBANforge.Sdk, version 1.5.0).

using var client = new IBANforgeClient(new IBANforgeOptions { ApiKey = Environment.GetEnvironmentVariable("IBANFORGE_API_KEY") });
var r = await client.ValidateIbanAsync("DE89 3704 0044 0532 0130 00");
Console.WriteLine($"{r.Valid} {r.Bic?.Code} {r.BankCodeCheck?.Status}");

Pass your own HttpClient (IHttpClientFactory) to the constructor when you have one; exceptions mirror the Java and TypeScript hierarchy. README.

Google Sheets

Extensions → Apps Script, then a custom function you can use as =VALIDATE_IBAN(A2):

function VALIDATE_IBAN(iban) {
  const res = UrlFetchApp.fetch("https://api.ibanforge.com/v1/iban/validate", {
    method: "post",
    contentType: "application/json",
    headers: { Authorization: "Bearer ifk_your_key" },
    payload: JSON.stringify({ iban: String(iban) }),
    muteHttpExceptions: true,
  });
  const d = JSON.parse(res.getContentText());
  return [[d.valid, d.bic ? d.bic.code : "", d.bank_code_check ? d.bank_code_check.status : ""]];
}

Mind your quota: one call per cell evaluation. For a whole column, prefer the batch endpoint from a script (up to 100 IBANs per call).

n8n

Install the community node — it wraps validation, BIC lookup, Swiss clearing and the compliance pre-check with a credentials screen:

Settings → Community nodes → Install → n8n-nodes-ibanforge

Self-hosted: npm install n8n-nodes-ibanforge. (Unverified community nodes run on self-hosted n8n; the verified listing for n8n Cloud is in progress.)

Odoo

An Odoo 18 module (AGPL-3) fills the BIC and the bank name on a partner bank account the moment an IBAN is typed, and creates or reuses the matching bank record. It is not on the Odoo Apps store yet; install it from the repository, at the root of the branch named after the Odoo version:

git clone -b 18.0 https://github.com/cammac-creator/ibanforge-odoo.git addons/ibanforge_bank_autofill

Update the apps list, install IBANforge bank autofill, then open Settings → IBANforge and paste your API key. Without a key the module stays offline and Odoo behaves exactly as stock. The README covers the SEPA and risk badge, and what it adds over native Odoo and the OCA module.

AI agents (MCP)

Claude Desktop, Claude Code, Cursor and any MCP client:

npx -y ibanforge-mcp        # stdio, 5 tools, free-tier key optional

Or the hosted transport, no install: https://api.ibanforge.com/mcp — it answers 10 free tool calls per IP per day with no key at all, which is the fastest way for an assistant to evaluate the data before you commit to anything.

What you get back

The response the recipes print (production answer, abridged):

{
  "valid": true,
  "bic": { "code": "COBADEFFXXX", "bank_name": "Commerzbank", "city": "Köln" },
  "bank_code_check": {
    "value": "37040044",
    "status": "verified",
    "register": "Deutsche Bundesbank Bankleitzahlendatei",
    "authoritative": true,
    "as_of": "2026-08"
  }
}

authoritative: true means the national register itself answered. Fields the data cannot support are null, never guessed — the full semantics explain what verified does and does not promise.

Related: What "verified" means · IBAN to BIC · Test IBAN generator · Data sources