# IBAN Validator — Structure, Checksum & Bank Code (`sourcerow/iban-validator`) Actor

Validate IBANs in bulk against the ISO 13616 registry — structure, length, mod-97 checksum, plus the country, the bank code and why an invalid one is invalid. No external service is called.

- **URL**: https://apify.com/sourcerow/iban-validator.md
- **Developed by:** [SourceRow](https://apify.com/sourcerow) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 iban checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Validate IBANs in bulk and identify why the invalid ones are invalid. Structure,
length, mod-97 checksum, country and bank code. No API key, no external service,
nothing that can rate-limit you.

### What it does

Send IBANs, receive a table with one row per number in the order supplied, 19
fields per row, stating whether each number is valid and what is wrong with the
ones that are not.

The check is the full ISO 13616 one: the country prefix, the length that country
uses, the character-by-character structure, and the mod-97 checksum that catches
mistyped and transposed digits.

Most validators answer yes or no. This one names the problem:

| reason | what happened |
|---|---|
| `wrong_length_for_country` | Germany expects 22 characters, this has 21 |
| `does_not_match_country_structure` | a letter where that country allows only digits |
| `checksum_failed` | structure is correct, so the digits contain a typo |
| `country_not_in_registry` | that country does not use IBAN |
| `check_digits_not_numeric` | positions 3 and 4 must be digits |

A wrong length usually means a spreadsheet truncated the column. A failed
checksum means the number was typed incorrectly. Those are different problems
with different fixes, and a plain "invalid" identifies neither.

### What you get

19 fields per row: `input`, `iban`, `formatted`, `result`, `reason`,
`country_code`, `country_name`, `check_digits`, `length`, `expected_length`,
`bban`, `bban_structure`, `bank_identifier`, `segments`, `checksum_passed`,
`standard`, `source_url`, `checked_at`, `issues`.

The table view shows 13 of them; all 19 are in the JSON, CSV and Excel downloads.

### Input

| Field | Meaning |
|---|---|
| `ibans` | The numbers to check. Spaces and dashes are normalised. |
| `ibansText` | A pasted list instead, one per line or comma-separated. |
| `maxIbans` | Stop after this many. `0` removes the cap. |

```json
{
  "ibansText": "IT60X0542811101000000123456\nGB82 WEST 1234 5698 7654 32\nDE89370400440532013000",
  "maxIbans": 1000
}
```

The values already present in those fields are examples, so that starting a run
without entering anything returns something real. Supply input of your own and
they are dropped: rows you did not ask for are not charged.

### Sample output

One complete record:

```json
{
  "input": "IT60X0542811101000000123456",
  "iban": "IT60X0542811101000000123456",
  "formatted": "IT60 X054 2811 1010 0000 0123 456",
  "result": "valid",
  "reason": null,
  "country_code": "IT",
  "country_name": "Italy",
  "check_digits": "60",
  "length": 27,
  "expected_length": 27,
  "bban": "X0542811101000000123456",
  "bban_structure": "1!a5!n5!n12!c",
  "bank_identifier": "05428",
  "segments": "X 05428 11101 000000123456",
  "checksum_passed": true,
  "standard": "ISO 13616",
  "source_url": "https://www.swift.com/standards/data-standards/iban-international-bank-account-number",
  "checked_at": "2026-08-28T14:19:59Z",
  "issues": ""
}
```

An invalid number keeps the same shape: `result` becomes `invalid`, `reason`
names the problem, and fields that cannot be determined are `null`.

### Pricing

| Event | Per 1,000 | Notes |
|---|---|---|
| IBAN checked | $1.00 | Every number supplied receives an answer, so every row is charged |

There is no start fee and no per-row dataset fee.

### What it does not do

**It does not confirm the account exists.** No offline check can. It confirms
the number is well formed and internally consistent, which catches typos and
truncations. It says nothing about whether the account is open or belongs to the
expected holder.

**No BIC, no bank name, no SEPA reachability.** Paid IBAN services often include
those because they query bank directories. This Actor queries nothing. For SEPA
reachability, use a service that calls a directory.

**Free libraries perform the same arithmetic.** `schwifty` in Python,
`ibantools` in JavaScript. With a developer and a codebase, those are the better
option. This Actor is for a list in a spreadsheet and no code to write.

**89 countries, which is the entire registry.** Numbers from countries that do
not use IBAN return `country_not_in_registry`, with the checksum result
alongside.

### Notes

Run it before a payment batch rather than after. A `checksum_failed` caught in
advance is a payment that does not bounce.

`wrong_length_for_country` on many rows at once usually indicates a truncated
spreadsheet column rather than bad source data.

`bank_identifier` groups counterparties by bank. Germany returns the eight-digit
Bankleitzahl, the Netherlands returns `ABNA`, Italy returns the five-digit ABI.
The single-character Italian CIN is not mistaken for a bank code.

`checksum_passed` is reported separately from `result`. A US account number is
not a valid IBAN, because the US does not use the scheme, but a passing checksum
is still reported. That combination usually indicates a real account in a
country outside the registry.

### Support

Open the **Issues** tab. One specific IBAN in a report can be checked in
seconds; a description of the symptom cannot.

### Licence and attribution

IBAN structures follow the ISO 13616 IBAN Registry, published by SWIFT as the
registration authority. Validation is arithmetic and calls no external service.
Nothing is retained: the numbers supplied are checked and returned.

# Actor input Schema

## `ibans` (type: `array`):

Bank account numbers to check. Spaces and dashes are cleaned up for you.

## `ibansText` (type: `string`):

Paste a list here instead of the field above. One per line or comma-separated.

## `maxIbans` (type: `integer`):

Stop after this many. **0 removes the cap.**

## Actor input object example

```json
{
  "ibans": [
    "GB82 WEST 1234 5698 7654 32",
    "IT60X0542811101000000123456",
    "DE89370400440532013000",
    "DE8937040044053201300"
  ],
  "maxIbans": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "ibans": [
        "GB82 WEST 1234 5698 7654 32",
        "IT60X0542811101000000123456",
        "DE89370400440532013000",
        "DE8937040044053201300"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sourcerow/iban-validator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "ibans": [
        "GB82 WEST 1234 5698 7654 32",
        "IT60X0542811101000000123456",
        "DE89370400440532013000",
        "DE8937040044053201300",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("sourcerow/iban-validator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "ibans": [
    "GB82 WEST 1234 5698 7654 32",
    "IT60X0542811101000000123456",
    "DE89370400440532013000",
    "DE8937040044053201300"
  ]
}' |
apify call sourcerow/iban-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sourcerow/iban-validator"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tXJMRQpmdNOkrXDtA/builds/eg7NYta1XUovX2wvw/openapi.json
