Endpoint
| Method | GET |
| URL | https://ibancodecheck.com/api/iban/{iban} |
| Auth | None required for the free per-IP allowance. An IPNOVA API key (free account at api.ipnova.com) applies your plan allowance instead: send it as the X-Api-Key header or the ?key= query parameter. Keyed responses carry X-Credits-Remaining and X-Credits-Used. |
| Rate limit | 100 requests a day and 30 a minute, per IP (see X-RateLimit-Remaining header) |
| CORS | Access-Control-Allow-Origin: * |
| Privacy | IBANs are never stored or logged; responses are no-store |
Plans
One key. Twelve APIs.
A free IPNOVA API account gives you 5,000 lookups a month across every API below, 60 a minute, no card, for evaluation and small projects. Paid plans from $19 a month for production volumes, with a commercial licence and a hard cap instead of overage billing.
Takes a minute. Send it as X-Api-Key or ?key=.
Without a key this API answers 100 requests a day per IP address, for evaluation and personal use. Try it: curl https://ibancodecheck.com/api/iban/DE89370400440532013000
Example Request
| curl | curl https://ibancodecheck.com/api/iban/DE89370400440532013000 |
| JavaScript | const r = await fetch('https://ibancodecheck.com/api/iban/DE89370400440532013000').then(r => r.json()); |
| PHP | $r = json_decode(file_get_contents('https://ibancodecheck.com/api/iban/DE89370400440532013000'), true); |
| Python | r = requests.get('https://ibancodecheck.com/api/iban/DE89370400440532013000').json() |
Response Fields
| Field | Type | Description |
|---|---|---|
data.valid | boolean | Overall verdict: format, length, and checksum all pass |
data.iban / data.formatted | string | Normalized and print-formatted (groups of 4) versions |
data.country_code / data.country | string | ISO country of the IBAN |
data.sepa | boolean | Whether the country participates in SEPA |
data.length_ok / data.checksum_ok | boolean | Individual check results for precise error messages |
data.check_digits | string | Positions 3 and 4 |
data.bank_code | string | Domestic bank code, where the position is defined for the country |
data.error | string|null | Human-readable reason when invalid |
Errors
Every non-200 response uses the same envelope: success: false, an error flag, a machine-readable reason, a human message, and a docs link back to this page. A structurally wrong IBAN (bad length, bad checksum, unknown country) still returns 200 with valid: false and data.error, so your form can show a helpful message; only input that is not IBAN-shaped at all fails with 400.
| Status | Reason | Meaning |
|---|---|---|
400 | invalid_input | Input is not IBAN-shaped at all |
401 | invalid_key | The supplied API key is unknown or revoked |
404 | unknown_endpoint | Path under /api/ does not match a published endpoint |
429 | rate_limit | Too many requests in the last minute (Retry-After: 60) |
429 | daily_limit | Keyless per-IP daily cap reached |
429 | credits_exhausted | Keyed monthly allowance used up |
Example, input that is not IBAN-shaped:
{"success": false, "error": true, "reason": "invalid_input", "message": "Provide a value shaped like an IBAN.", "docs": "https://ibancodecheck.com/iban-api"}
Tip: Validate Client-Side First
The mod-97 algorithm is simple enough to run in the browser (our own checker does exactly that). A common pattern: validate client-side for instant feedback, then re-validate server-side via this API before accepting the form.
Frequently Asked Questions
Is the API really free?
Yes. No API key, no registration, no credit card. Each IP address can make up to 100 requests per day, and CORS is enabled so you can call it directly from the browser.
Are IBANs stored?
No. Validation is purely algorithmic (ISO 13616 registry rules plus the mod-97 checksum) and IBANs are never written to disk or logged. Responses are served with Cache-Control: no-store.
Can I test it right now?
Try /api/iban/DE89370400440532013000 in your browser (the published ISO sample for Germany).
What does the API check?
Country code against the ISO 13616 registry, exact length for that country, and the ISO 7064 mod-97 checksum. It also extracts the check digits and the domestic bank code where the position is defined.
Does a valid response mean the account exists?
No. Validation confirms the number is structurally correct with no typos. It cannot confirm the account is open or who owns it.