# IBAN Validator & BIC Lookup API: Bank Code, Country, SEPA (`actose/iban-validator-bic-lookup`) Actor

Bulk IBAN validation: length, mod-97 check digits, country structure and national keys, plus bank code, account number, BIC and bank name from open registries. Invalid IBANs flagged free. No API key, no login. MCP-ready for AI agents. Pay per valid IBAN, no monthly rental. $2 per 1,000 IBANs.

- **URL**: https://apify.com/actose/iban-validator-bic-lookup.md
- **Developed by:** [ABM](https://apify.com/actose) (community)
- **Categories:** Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 valid ibans

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## IBAN Validator & BIC Lookup API: Bank Code, Country, SEPA

**$2 per 1,000 valid IBANs. Invalid, empty and duplicate values are free. No API key, no login, no monthly rental.**

Validate IBANs in bulk before you send SEPA transfers, payroll or supplier payments. For every IBAN this Actor checks:

- **Length** for the country (e.g. 22 for Germany, 27 for France)
- **Check digits** (ISO 13616 modulo 97)
- **Country BBAN structure** (which positions must be letters or digits)
- **National check digits** inside the BBAN when the country has them (French RIB key, Spanish, Italian CIN, Belgian, Norwegian, Polish keys…)

Then it extracts the **country, bank code, branch code, account number** and adds the **BIC (SWIFT code) and bank name** from the open national bank registries (Bundesbank, Banque de France, SIX, National Bank of Belgium, and ~40 more).

Everything is computed offline inside the Actor: no third-party API, no rate limit, no IBAN sent anywhere else. 100,000 IBANs take about a minute.

### How much does it cost?

You pay **$0.002 per valid IBAN** (event `iban-validated`), which is **$2 per 1,000 valid IBANs**.

| You send | Valid | Invalid / duplicates | You pay |
|---|---|---|---|
| 1,000 supplier IBANs | 970 | 30 | 970 × $0.002 = **$1.94** |
| 10,000 employee IBANs | 9,900 | 100 | **$19.80** |
| 3 IBANs (test) | 3 | 0 | **$0.006** |

Invalid IBANs are still returned in the dataset with the exact reason, **free of charge**. If you set a maximum cost per run, the Actor stops cleanly when the budget is reached.

### Input

```json
{
  "ibans": [
    "DE89370400440532013000",
    "fr76 3000 6000 0112 3456 7890 189",
    "GB82WEST12345698765432",
    "DE89370400440532013001"
  ],
  "validateNationalChecksum": true,
  "deduplicate": true
}
```

| Field | Type | Description |
|---|---|---|
| `ibans` | array of strings | IBANs, one per item. Spaces, dashes, lowercase and an `IBAN` prefix are accepted. A single string with IBANs separated by new lines, commas or semicolons also works when calling the API. |
| `ibansText` | string | Alternative: paste an Excel column or CSV text (separated by new lines, commas, semicolons or tabs). |
| `validateNationalChecksum` | boolean (default `true`) | Also verify the domestic check digits inside the BBAN. |
| `deduplicate` | boolean (default `true`) | Return and charge each IBAN only once. |

Up to 100,000 IBANs per run.

### Output

One object per IBAN in the dataset:

```json
{
  "input": "DE89370400440532013000",
  "position": 1,
  "iban": "DE89370400440532013000",
  "ibanFormatted": "DE89 3704 0044 0532 0130 00",
  "isValid": true,
  "errorCode": null,
  "errorMessage": null,
  "countryCode": "DE",
  "countryName": "Germany",
  "isSepaCountry": true,
  "checkDigits": "89",
  "bban": "370400440532013000",
  "length": 22,
  "expectedLength": 22,
  "bankCode": "37040044",
  "branchCode": null,
  "accountNumber": "0532013000",
  "nationalCheckDigits": null,
  "currencyCode": "EUR",
  "bic": "COBADEFFXXX",
  "bankName": "Commerzbank",
  "bankShortName": "Commerzbank Köln",
  "bicFound": true,
  "nationalChecksumVerified": true,
  "charged": true,
  "checkedAt": "2026-10-22T08:00:00+00:00"
}
```

An invalid IBAN (free):

```json
{
  "input": "DE89370400440532013001",
  "position": 4,
  "iban": "DE89370400440532013001",
  "isValid": false,
  "errorCode": "INVALID_CHECKSUM",
  "errorMessage": "Check digits (mod 97) do not match: probably a typo. (Invalid checksum digits)",
  "countryCode": "DE",
  "length": 22,
  "expectedLength": 22,
  "bic": null,
  "charged": false
}
```

Error codes: `EMPTY`, `INVALID_CHARACTERS`, `INVALID_COUNTRY_CODE`, `INVALID_LENGTH`, `INVALID_STRUCTURE`, `INVALID_CHECKSUM`, `INVALID_NATIONAL_CHECKSUM`, `INVALID_BANK_CODE`, `INVALID_BRANCH_CODE`, `INVALID_ACCOUNT_CODE`, `INVALID`.

A run summary (counts, error codes, list of invalid IBANs) is saved in the key-value store under `SUMMARY` and linked in the run's Output tab.

### Use cases

#### 1. Payroll: check employee IBANs before the monthly SEPA file

**Who:** payroll manager of a 2,400-employee company paying salaries in France, Spain and Germany.
**Input:**

```json
{ "ibansText": "FR7630006000011234567890189\nES9121000418450200051332\nDE89370400440532013000\nFR7630006000011234567890188", "validateNationalChecksum": true }
```

**Output (extract):**

```json
[
  { "iban": "FR7630006000011234567890189", "isValid": true, "bankCode": "30006", "branchCode": "00001", "bic": "AGRIFRPPXXX" },
  { "iban": "FR7630006000011234567890188", "isValid": false, "errorCode": "INVALID_CHECKSUM" }
]
```

**Then:** the 3–5 invalid IBANs of the month are sent back to HR before the payment file is generated, avoiding rejected transfers (R-transactions cost €5–€15 each at most banks). Cost: 2,400 × $0.002 = **$4.80 per month**.

#### 2. Accounts payable: clean the supplier master data and fill missing BICs

**Who:** AP team in a mid-size distributor with 6,000 suppliers exported from the ERP.
**Input:**

```json
{ "ibans": ["NL91ABNA0417164300", "BE68539007547034", "IT60X0542811101000000123456", "AT611904300234573201"] }
```

**Output (extract):**

```json
[
  { "iban": "NL91ABNA0417164300", "isValid": true, "bic": "ABNANL2AXXX", "bankName": "ABN AMRO BANK N.V." },
  { "iban": "IT60X0542811101000000123456", "isValid": true, "bankCode": "05428", "branchCode": "11101", "nationalCheckDigits": "X" }
]
```

**Then:** the result is exported to CSV and re-imported in the ERP: the BIC column is filled for every bank found in the registries, invalid IBANs are flagged for the supplier onboarding team. 6,000 IBANs = **$12**, done in seconds.

#### 3. Fintech / marketplace onboarding: validate payout IBANs in real time

**Who:** a marketplace that pays sellers in 15 European countries, calling the Actor from its onboarding backend.
**Input:**

```json
{ "ibans": ["PL61109010140000071219812874"], "deduplicate": true }
```

**Output (extract):**

```json
[{ "iban": "PL61109010140000071219812874", "isValid": true, "countryCode": "PL", "isSepaCountry": true, "bankCode": "10901014", "bic": "WBKPPLPPXXX" }]
```

**Then:** the seller form refuses wrong IBANs immediately and shows the bank name for confirmation ("Is your bank Santander Bank Polska?"). At 20,000 sign-ups per month = **$40**.

### Call it from the API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<USERNAME>/iban-validator-bic-lookup").call(run_input={
    "ibans": ["DE89370400440532013000", "GB82WEST12345698765432"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["iban"], item["isValid"], item["bic"], item["errorMessage"])
```

**JavaScript**

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('<USERNAME>/iban-validator-bic-lookup').call({
    ibans: ['DE89370400440532013000', 'GB82WEST12345698765432'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => !i.isValid));
```

**Synchronous HTTP (one call, JSON back):**

```
POST https://api.apify.com/v2/acts/<USERNAME>~iban-validator-bic-lookup/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
{"ibans": ["DE89370400440532013000"]}
```

### Automation (Make, n8n, Zapier, Google Sheets)

Example with **n8n** or **Make**: every day at 7:00, read the "New suppliers" Google Sheet → run this Actor with the IBAN column in `ibansText` → write `isValid`, `bic` and `errorMessage` back to the sheet → send a Slack message to AP for each row where `isValid` is false. In Zapier, use the Apify app "Run Actor" action with the same input. Results can also be exported directly from the dataset as CSV, Excel, JSON or XML.

### Use with AI agents (MCP)

The Actor is available through the Apify MCP server, so Claude, Cursor, ChatGPT and other AI agents can call it as a tool: "Check these 40 IBANs and tell me which ones will be rejected". The output is flat JSON with explicit `isValid`, `errorCode` and `errorMessage` fields, easy for an LLM to reason about.

### FAQ

**Does it check that the account really exists?**
No. Nobody can do that without access to the bank. It proves the IBAN is well-formed, has correct check digits and a bank code consistent with the country. This catches typos and most copy-paste errors, which are the main cause of rejected SEPA transfers.

**Where does the BIC come from?**
From the open bank registries published by national central banks and payment associations, bundled in the Actor. When the bank is not in a registry, `bic` is `null` and `bicFound` is `false`; the IBAN is still validated (and charged).

**Are my IBANs sent to a third party?**
No. Validation and BIC lookup run inside the Actor, no external request is made.

**Which countries are supported?**
All ~90 countries that use IBAN (SWIFT IBAN registry). BIC/bank name lookup covers about 45 countries, mostly in Europe (DE, FR, GB, ES, IT, NL, BE, AT, CH, PL, SE, NO, DK, FI, PT, IE, LU, CZ, SK, HU, RO, BG, HR, SI, LT, LV, EE…).

**Why was I not charged for some rows?**
Only valid IBANs are charged. Invalid, empty and duplicate values are free.

### Limits

- A valid IBAN does not guarantee that the account is open or belongs to the expected person (use Verification of Payee / SEPA name-check for that).
- BIC lookup depends on the national registry coverage; for some banks (and most non-European countries) `bic` is null.
- National check digits are verified only for countries that define them.
- 100,000 IBANs per run; split bigger files into several runs.

# Actor input Schema

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

One IBAN per line. Spaces, dashes, lowercase letters and an 'IBAN' prefix are accepted (e.g. 'fr76 3000 6000 0112 3456 7890 189'). Up to 100,000 per run.

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

Alternative to the list: paste a column from Excel or a CSV export. IBANs can be separated by new lines, commas, semicolons or tabs.

## `validateNationalChecksum` (type: `boolean`):

Also verify the domestic check digits inside the BBAN (e.g. French RIB key, Spanish, Italian CIN, Belgian, Norwegian keys) for the countries that have them. Recommended before SEPA payments.

## `deduplicate` (type: `boolean`):

Return (and charge) each IBAN only once even if it appears several times in the input.

## Actor input object example

```json
{
  "ibans": [
    "DE89370400440532013000",
    "FR7630006000011234567890189",
    "GB82WEST12345698765432"
  ],
  "ibansText": "",
  "validateNationalChecksum": true,
  "deduplicate": true
}
```

# Actor output Schema

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

One row per IBAN: validity, error reason, country, bank code, BIC and bank name.

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

Counts of valid, invalid and duplicate IBANs, error codes and the list of invalid IBANs.

# 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": [
        "DE89370400440532013000",
        "FR7630006000011234567890189",
        "GB82WEST12345698765432"
    ],
    "ibansText": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("actose/iban-validator-bic-lookup").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": [
        "DE89370400440532013000",
        "FR7630006000011234567890189",
        "GB82WEST12345698765432",
    ],
    "ibansText": "",
}

# Run the Actor and wait for it to finish
run = client.actor("actose/iban-validator-bic-lookup").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": [
    "DE89370400440532013000",
    "FR7630006000011234567890189",
    "GB82WEST12345698765432"
  ],
  "ibansText": ""
}' |
apify call actose/iban-validator-bic-lookup --silent --output-dataset

```

## MCP server setup

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

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/gM8swL8OPteEGGHxr/builds/Uyyx0HUDqye4gtFrM/openapi.json
