# IBAN Validator API: Checksum, Country & SEPA (`stas_k/iban-validator`) Actor

Shape-only validators pass made-up numbers as valid. This one does the real mod-97 math, country and SEPA from the official registry, and names the exact reason a number fails, including the check digits it should have had. Malformed lines are free.

- **URL**: https://apify.com/stas_k/iban-validator.md
- **Developed by:** [Stas K](https://apify.com/stas_k) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 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?

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: Checksum, Country & SEPA

Most "IBAN validators" check the **shape** of the string and answer *valid*. A made-up
number passes them: right country code, right length, right letters - and the money is
gone when the payout batch runs. This Actor does the arithmetic a bank does.

Give it one IBAN per line, or paste a whole invoice and it finds them itself.

### What the answer contains

| field | meaning |
|---|---|
| `valid` | `true` only when the **mod-97 checksum** holds (and the BIC, if given, matches) |
| `status` | `VALID`, `BAD_CHECKSUM`, `BAD_LENGTH`, `UNKNOWN_COUNTRY`, `BAD_CHARACTERS`, `BAD_FORMAT`, `BAD_BIC`, `EMPTY` |
| `expectedCheckDigits` | when the checksum fails - **the pair the number should have had** |
| `country`, `countryCode` | from the official IBAN registry (80+ countries), not from the string alone |
| `sepa` | whether that country is in the SEPA area |
| `printed` | the number the way banks print it, groups of four |
| `bban` | the national part, for your own downstream checks |

### What it refuses to overclaim

- A **BIC** is checked for shape and for its country: `DEUTGB2L` with a German IBAN is a
  contradiction and is reported as one. We do **not** claim to know which bank owns the
  account - the IBAN alone cannot prove that, so we say nothing.
- A country we do not know is `UNKNOWN_COUNTRY`, never a guess.
- Nothing is dropped silently: an empty line, a truncated number, a URL typed by mistake -
  each becomes its own row with a reason.

### Pricing

**$1.00 per 1,000 IBANs whose checksum was actually computed** ($0.001 each), and platform
usage is included in that price.

- A malformed line, an unknown country, an empty line - **free**, and still reported.
- The input is pure arithmetic: no proxy, no network calls, so a run of 10,000 numbers is
  a second of work, not a scraping bill.

### Typical use

- validating a payout batch before it leaves your ERP;
- onboarding check for a B2B customer's bank details;
- cleaning a supplier file where a typo sends money to nowhere;
- catching `O`/`0` and `l`/`1` typos that pass every regex.

### Example input

```json
{
  "ibans": "DE89 3704 0044 0532 0130 00\nGB82 WEST 1234 5698 7654 32\nDE89 3704 0044 0532 0130 01",
  "bics": "DEUTDEFF\n\n"
}
```

The third number has the right shape and the wrong arithmetic - the Actor answers
`BAD_CHECKSUM` and names the check digits it should have had.

### API

```bash
curl "https://api.apify.com/v2/acts/stas_k~iban-validator/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ibans": "NL91ABNA0417164300"}'
```

### Notes

- Spaces and dashes are ignored, upper/lower case is normalised; characters themselves are
  never "corrected" - a letter `O` where a zero was meant is caught by arithmetic, not by
  silently rewriting the input.
- Up to 10,000 IBANs per run.

#### Spending cap

If you do not set a spending cap, Apify applies its own default (about $4.63 per run). When that cap is reached the run stops early: the remaining items are skipped and you are charged only for what was actually delivered. For a full pass, set `maxTotalChargeUsd` in the run options.

# Actor input Schema

## `ibans` (type: `string`):

One per line. Spaces and dashes are ignored, so you can paste them exactly as your bank prints them. Up to 10,000 per run.

## `text` (type: `string`):

Used only when 'IBANs to check' is empty: IBANs are pulled out of an invoice, an email or any pasted text, in the order they appear.

## `bics` (type: `string`):

8 or 11 characters, one per line. We prove one thing about them: the country inside the BIC must match the IBAN. We do not claim to know the account's bank.

## Actor input object example

```json
{
  "ibans": "DE89 3704 0044 0532 0130 00\nGB82 WEST 1234 5698 7654 32\nDE89 3704 0044 0532 0130 01"
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per IBAN: whether the mod-97 checksum holds, which country it belongs to, whether that country is in SEPA, and the exact reason a number was rejected.

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

Counts by status, how many rows were billable, and how many were stopped by the spending cap.

# 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": `DE89 3704 0044 0532 0130 00
GB82 WEST 1234 5698 7654 32
DE89 3704 0044 0532 0130 01`
};

// Run the Actor and wait for it to finish
const run = await client.actor("stas_k/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": """DE89 3704 0044 0532 0130 00
GB82 WEST 1234 5698 7654 32
DE89 3704 0044 0532 0130 01""" }

# Run the Actor and wait for it to finish
run = client.actor("stas_k/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": "DE89 3704 0044 0532 0130 00\\nGB82 WEST 1234 5698 7654 32\\nDE89 3704 0044 0532 0130 01"
}' |
apify call stas_k/iban-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stas_k/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/Sm7LuEa8ulgbkrws3/builds/TJZZJyRXIfL6m8sLl/openapi.json
