REST API + QA tools

IBAN Generator API for payment QA.

Generate IBANs, validate IBAN lists, create synthetic profiles, export datasets, and build edge-case files. API-key endpoints are metered by your plan; web dataset tools can also use 24h Pass credits for one-day work.

Free IBAN QA starter kit

Put ten explainable format/checksum cases into your payment-form tests. Each case separates format, MOD-97, national checksum, registry match and provider scope, with a pinned source version. Run either verifier offline with no API key.

python3 verify.py
node --test verify.test.js

The example covers these five country patterns only. It checks format and checksum, not bank-account existence or ownership. If a checksum-valid value still fails your integration, follow the layer-by-layer debugging guide.

Make your first Free API request

Create an API key and set IBANGEN_API_KEY in your environment. Country-only generation uses two of your Free plan's 50 API credits:

curl --fail-with-body https://ibangen.com/api/v1/generate \
  -H "X-API-Key: $IBANGEN_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"country":"Germany","quantity":2}'

Need a specific bank or a reusable dataset? Check coverage, then use Pro at $29/month for bank targeting and saved workflows.

From zero to a verified fixture

Use this four-step path for a first integration: create an API key, generate one deterministic IBAN, inspect the coverage object, then rerun the same request with the seed in CI.

1. API key 2. Generate 3. Verify coverage 4. Pin the seed
curl -X POST https://ibangen.com/api/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"country":"Germany","quantity":1,"seed":"checkout-ci-v1","include_bank_details":true}'
What to assert in CI: valid == true, the requested country matches, coverage.match_status is matched when you target a bank/BIC, and the returned seed is unchanged. A no-match response is explicit and should not silently fall back to another bank.

Bank-field preflight for server applications

Try the banking CSV preflight pilot: map test-data columns, inspect the credit quote and download row-by-row checks using your existing allowance.

For an application that receives new bank details regularly, start with one supported-country integration. Keep format/checksum checks separate from observed bank metadata. An unknown bank lookup is not an invalid account, and a valid checksum does not establish account existence, ownership or payment acceptance.

Download the dependency-free Python integration example. Keep the API key on your server. The example has a timeout, blocks redirects, does not log input values and never automatically retries a chargeable request.

from bank_metadata_preflight import preflight, PreflightUnavailable

try:
    results = preflight(synthetic_test_ibans)
except PreflightUnavailable:
    # Defer the check. Do not label a provider timeout as an invalid account.
    results = None

Each request supports up to 100 rows. Premium metadata consumes API and SWIFT credits: Pro currently includes 10,000 API credits and 2,000 SWIFT/BIC reveals per month. Test coverage with synthetic inputs first; agree on data handling before using real customer records.

Integration artifacts

Use the machine-readable contract and starter assets below to keep integrations reproducible. The OpenAPI and Postman files describe the same stable paths shown in this page; the SDK raises an error with both HTTP status and JSON payload.

Async contract: a statement upload returns 202 with status=pending_analysis; poll the review id until completed, then delete it with DELETE /statement-validator/review/{review_id} when the case is closed. The example webhook is a consumer payload contract, not a claim that outbound webhooks are enabled for every account.

MCP server for AI agents

Give Claude, Cursor or any Model Context Protocol client three IBANgen tools: validate_ibans (works without a key for up to 10 IBANs per call), generate_test_ibans and lookup_bank. The server is open source, published on PyPI and listed in the official MCP Registry as io.github.offx366/ibangen-mcp.

pip install ibangen-mcp

Add it to Claude Desktop, Claude Code or .cursor/mcp.json:

{
  "mcpServers": {
    "ibangen": {
      "command": "ibangen-mcp",
      "env": { "IBANGEN_API_KEY": "your_api_key_here" }
    }
  }
}

Authentication

Send your account API key in every REST request. Log in to show your real key in these examples.

X-API-Key: your_api_key_here
API endpoints consume API call credits. Batch generate/validate requests are metered per IBAN row, not just per HTTP request. Paid bank metadata also consumes SWIFT/BIC reveal credits per returned row.
Correlation: every API response includes an X-Request-ID header. You may send a short ASCII X-Request-ID value with a request; otherwise IBANgen generates one. Keep it with your CI or support logs. It is a correlation value, not an idempotency key.

API Onboarding Path

Use Pro for self-serve API work. Use Business when a team needs higher monthly volume, saved QA datasets, exact bank/BIC targeting, or annual invoice procurement.

Current Tiers

These are the real product limits currently enforced by the app.

Plan Price API calls Profiles SWIFT/BIC reveals Exports
Free Free 50 5 0 0
24h Pass $4.99 one-time 100 / 24h 10 / 24h 40 / 24h 3 / 24h
Starter $19/month 2,000 / month 200 / month 200 / month 50 / month
Pro $29/month 10,000 / month 1,000 / month 2,000 / month 500 / month
Business $99/month 100,000 / month 10,000 / month 10,000 / month 2,000 / month
Enterprise $190/month 250,000 / month 25,000 / month 25,000 / month 5,000 / month

API Playground

Run a small live request from this page. It uses your real API key when you are logged in and consumes the same API credits as a normal request.

Log in to run the playground with your real API key. Public examples below still show cURL, Python, JavaScript, PowerShell, and PHP.
Log in to use playground

Generate IBAN

POST/api/v1/generate
API key required quantity: 1-100 Consumes API credits Bank targeting: Pro+ Exact BIC: Business+

Generates valid IBANs for supported countries. quantity consumes the same number of API credits, and paid SWIFT/BIC plus bank metadata consumes the same number of reveal credits. Paid results can include official GLEIF legal-entity data, EPC payment-scheme participation, and supported domestic bank-registry fields under bank_intelligence. Free API keys receive locked premium fields. Pro and Business API keys can also request targeted generation against bank records when a country supports bank-code generation.

cURL
curl -X POST https://ibangen.com/api/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"country":"Germany","quantity":3}'
Python
import requests

response = requests.post(
    "https://ibangen.com/api/v1/generate",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": "your_api_key_here",
    },
    json={"country": "Germany", "quantity": 3},
)
print(response.json())
JavaScript
const response = await fetch("https://ibangen.com/api/v1/generate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here"
  },
  body: JSON.stringify({ country: "Germany", quantity: 3 })
});

console.log(await response.json());
PowerShell
$headers = @{
  "Content-Type" = "application/json"
  "X-API-Key" = "your_api_key_here"
}

$body = @{ country = "Germany"; quantity = 3 } | ConvertTo-Json
Invoke-RestMethod -Uri "https://ibangen.com/api/v1/generate" -Method Post -Body $body -Headers $headers
PHP
 true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/json",
    "X-API-Key: your_api_key_here"
  ],
  CURLOPT_POSTFIELDS => json_encode(["country" => "Germany", "quantity" => 3])
]);
echo curl_exec($ch);
?>
[
  {
    "iban": "DE89370400440532013000",
    "valid": true,
    "swift_code": "COBADEFFXXX",
    "bank_name": "Commerzbank",
    "bank_city": "Frankfurt am Main",
    "premium_fields_locked": false,
    "bank_intelligence": {
      "lei": "851WYGNLUQLFZBSYGB56",
      "legal_name": "COMMERZBANK Aktiengesellschaft",
      "entity_status": "ACTIVE",
      "registration_status": "ISSUED",
      "payment_schemes": ["sct", "sct_inst", "sdd_b2b", "sdd_core", "vop"],
      "domestic_registry": {
        "bank_code": "37040044",
        "account_checksum_method": "13"
      }
    }
  }
]

Targeted generation

Use the optional targeting object when you need generated IBANs tied to supported bank records. Free users can browse targeting options in the UI, but API generation with targeting.city, targeting.bank, or targeting.bic requires paid access.

Field Plan Behavior
targeting.city Paid access Generates against a supported bank record from the selected city. It can be combined with bank or BIC targeting.
targeting.bank Pro+ Generates against a matching bank record, using the selected bank code when that country exposes one.
targeting.bic Business+ Generates against an exact BIC/branch record when the country generator can honor it.

Compatibility aliases are accepted for integrations that already send top-level fields: custom_city, custom_bank, custom_bic, bank_name, bic, and swift_code.

Pro bank-targeted request
curl -X POST https://ibangen.com/api/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "country": "Luxembourg",
    "quantity": 2,
    "targeting": {
      "city": "LUXEMBOURG",
      "bank": "BANQUE DE LUXEMBOURG S.A."
    }
  }'
Business exact-BIC request
{
  "country": "Luxembourg",
  "quantity": 1,
  "targeting": {
    "bic": "BLUXLULL"
  }
}
Targeted response fields
[
  {
    "iban": "LU340088078217992601",
    "valid": true,
    "swift_code": "BLUXLULL",
    "bank_name": "BANQUE DE LUXEMBOURG S.A.",
    "bank_city": "LUXEMBOURG",
    "premium_fields_locked": false,
    "custom_target": {
      "scope": "bank",
      "bank_name": "BANQUE DE LUXEMBOURG S.A.",
      "city": "LUXEMBOURG",
      "swift_code": "BLUXLULL",
      "match_level": "bank_code",
      "generated_bank_code": "008"
    }
  }
]
Targeting paywall error
{
  "error": "advanced_targeting_required",
  "required_plan": "Pro",
  "pricing_url": "/pricing?checkout=pro&intent=custom_bank",
  "message": "Pro is required for this targeted API generation option."
}

Validate IBAN

POST/api/v1/validate
Try without a key: 10 IBANs/request, 100/day Batch validation Consumes API credits

Validates IBAN structure/checksum. Each IBAN in the list consumes one API credit. City is visible to every API key; SWIFT/BIC, bank name, legal-entity details, payment rails, and domestic-registry fields are premium metadata, so paid API keys spend one reveal credit per IBAN and free API keys receive locked placeholders for those fields.

No key yet? Omit X-API-Key to try structural validation from your terminal: up to 10 IBANs per request and 100 per day per IP, with bank fields locked. Responses carry X-RateLimit-Remaining.

curl -X POST https://ibangen.com/api/v1/validate \
  -H "Content-Type: application/json" \
  -d '{"ibans":["DE89370400440532013000"]}'
cURL
curl -X POST https://ibangen.com/api/v1/validate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"ibans":["GB82WEST12345698765432","DE89370400440532013000"]}'
Python
import requests

response = requests.post(
    "https://ibangen.com/api/v1/validate",
    headers={"X-API-Key": "your_api_key_here"},
    json={"ibans": ["GB82WEST12345698765432", "DE89370400440532013000"]},
)
print(response.json())
JavaScript
const response = await fetch("https://ibangen.com/api/v1/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here"
  },
  body: JSON.stringify({
    ibans: ["GB82WEST12345698765432", "DE89370400440532013000"]
  })
});
console.log(await response.json());
PowerShell
$headers = @{
  "Content-Type" = "application/json"
  "X-API-Key" = "your_api_key_here"
}

$body = @{ ibans = @("GB82WEST12345698765432", "DE89370400440532013000") } | ConvertTo-Json
Invoke-RestMethod -Uri "https://ibangen.com/api/v1/validate" -Method Post -Body $body -Headers $headers
PHP
 ["GB82WEST12345698765432", "DE89370400440532013000"]];
$ch = curl_init("https://ibangen.com/api/v1/validate");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => ["Content-Type: application/json", "X-API-Key: your_api_key_here"],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);
echo curl_exec($ch);
?>

Response examples

Paid account or 24h Pass: validation returns premium bank metadata when available.

[
  {
    "iban": "FI1623114147337697",
    "valid": true,
    "swift_code": "NDEAFIHH",
    "bank_name": "NORDEA BANK AB (PUBL), FINNISH BRANCH",
    "bank_city": "HELSINKI",
    "bank_intelligence": {
      "legal_name": "Nordea Bank Abp",
      "entity_status": "ACTIVE",
      "payment_schemes": ["sct", "sct_inst", "sdd_b2b", "sdd_core", "vop"]
    },
    "premium_fields_locked": false
  }
]

Free API key: validation still returns valid/invalid status, but premium bank fields are locked.

[
  {
    "iban": "FI1623114147337697",
    "valid": true,
    "swift_code": "Hidden",
    "bank_name": "Hidden",
    "bank_city": "HELSINKI",
    "premium_fields_locked": true,
    "locked_fields": ["swift_code", "bank_name", "bank_intelligence"],
    "premium_unlock_url": "/pricing?checkout=day_pass&intent=swift"
  }
]

Bank Intelligence Registry

POST/api/v1/bank-intelligence/lookup
POST/api/v1/bank-intelligence/search
GET/api/v1/bank-intelligence/record/{id}
POST/api/v1/bank-intelligence/export
GET/api/v1/bank-intelligence/sources
GET/api/v1/bank-intelligence/changes
Starter lookup Pro search Business provenance Enterprise changes

Resolve BIC, LEI, domestic clearing codes, regulatory identifiers, and company numbers against normalized official snapshots. Lookup requests consume one API credit per identifier and return at most 25 matches for each identifier. Search requests reserve the requested result limit, so broader searches consume proportionally more API capacity.

curl -X POST https://ibangen.com/api/v1/bank-intelligence/lookup \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "identifiers": [
      {"type": "bic", "value": "COBADEFFXXX"},
      {"type": "lei", "value": "851WYGNLUQLFZBSYGB56"}
    ]
  }'
curl -X POST https://ibangen.com/api/v1/bank-intelligence/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "query": "Commerzbank",
    "country_code": "DE",
    "record_type": "bank",
    "limit": 20
  }'

Business responses include source attribution and payment-rail metadata when available. Record detail also exposes GLEIF parent relationships, while /sources lists snapshot dates, attribution, license markers, and row counts. Business can export up to 250 identifier queries as CSV with /export; Enterprise raises that to 1,000. An export consumes the identifier row count from API credits and one export credit. Enterprise can query monitored source changes with /changes?source_id=ecb_mfi&limit=100; the versioned registry-change/1.0 event schema documents the snapshot ID, before/after fields and detection timestamp.

Registry Watchlists

GET/POST/api/v1/registry/watchlists
GET/DELETE/api/v1/registry/watchlists/{watch_id}
GET/api/v1/registry/watchlists/{watch_id}/changes
GET/api/v1/registry/watchlists/{watch_id}/migration-fixture

Save a supported source/key pair, inspect field-level changes and generate a deterministic synthetic before/after fixture. Watchlists are user-scoped and plan-limited. The current worker queues pending verification alerts only; outbound email or webhook delivery is not implied by creating a watch.

curl -X POST https://ibangen.com/api/v1/registry/watchlists \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"source_id":"ecb_mfi","record_key":"DE001"}'

curl -H "X-API-Key: your_api_key_here" \
  https://ibangen.com/api/v1/registry/watchlists/{watch_id}/changes
Fail-closed contract: a missing or conflicting source record is reported as no match. The service does not invent a successor identifier or silently substitute another bank.

Registry Time Machine

GET/api/v1/registry/time-machine?source_id=...&record_key=...

Enterprise API access can inspect one bounded target across the current normalized record, published previous snapshot diffs and source-published upcoming effective dates. The response is evidence-first: it never fills missing history or predicts a future change. Pin registry.fingerprint and registry.version in CI when you need reproducible migration tests.

curl -G https://ibangen.com/api/v1/registry/time-machine \
  -H "X-API-Key: your_api_key_here" \
  --data-urlencode "source_id=ecb_mfi" \
  --data-urlencode "record_key=DE001"
Open the public preview

US routing numbers, generation and profiles

Use the same X-API-Key as the IBAN endpoints. US bank fields use routing and account numbers, not IBANs. These endpoints return JSON; keep your key on the server.

POST/api/v1/us/routing/generate

Free accounts can generate up to 10 synthetic rows per request; paid access permits up to 750. Synthetic generation uses no credits and free-account requests are rate limited. Omit seed for fresh values; supply a 1–100 character seed for reproducible results. This mode does not assert bank assignment.

curl https://ibangen.com/api/v1/us/routing/generate \
  -H 'X-API-Key: YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"mode":"synthetic","quantity":3,"seed":"qa-us-v1"}'
GET/api/v1/us/routing/targets

Search with ?q=credit%20union&limit=50&offset=0 (limit 1–100). Follow next_offset until null. Targets preserve the source hash and date. primary_aba_identity identifies a dated bank reference and does not confirm ACH/Fedwire eligibility. Primary ABA attribution: Nelson Anievas / fi-lookup-mcp, FFIEC NIC, FDIC and NCUA, CC BY 4.0.

POST/api/v1/us/routing/quote
POST/api/v1/us/routing/run

Fetch current targets, then use one target's exact target_id, source_sha256 and routing_number. Targeting requires an active Pro subscription (up to 150 rows) or Business/Enterprise (up to 750). Each generated row consumes one bank metadata credit. Quote returns the cost without a debit.

{
  "routing_numbers": ["ROUTING_FROM_TARGET"],
  "generate_tests": true,
  "seed": "qa-us-v1",
  "generation": {
    "target_id": "TARGET_ID_FROM_CATALOG",
    "source_sha256": "SOURCE_HASH_FROM_CATALOG",
    "quantity": 3
  }
}

POST this body to /quote. To execute, add max_credits equal to the quoted credits and a request_id containing current Unix milliseconds, a hyphen and 32 lowercase hexadecimal characters (for example a UUID without hyphens), then POST to /run. Repeat the identical body and key after a lost response: the saved result replays without a second debit. Keys expire after 24 hours; a changed payload or source requires a new quote and key. Generated cases are in rows[].test_cases.

GET/api/v1/us/routing/{routing_number}
POST/api/v1/us/routing/check-list

Lookup consumes one API credit. Bulk checks use the existing plan's search allowance and report their credits. For explicit cost confirmation and replay protection, use /quote and /run with routing_numbers and no generation object. Checksum, source observations and payment rails remain separate; unknown is not invalid. Neither operation verifies an account owner or payment acceptance.

POST/api/v1/us/routing/profile

Send {"mode":"synthetic","seed":"qa-us-v1","preview_only":true} for a free limited preview. Full paid AI profiles require profile access and confirm_credit:true with preview_only omitted or false; one successful profile consumes one profile credit. Retrying the same seed and target replays the stored profile. For bank targeting, use mode targeted and the same generation object as above. Error responses expose required credits or subscription recovery; a preview never debits a profile credit.

Try US generation · Try routing validation

Fixture Manifest

GET/api/v1/fixture-manifest/spec
GET/fixture-manifest/schema/1.0
POST/api/v1/fixture-manifest/compile

Compile a portable ibangen-fixture-manifest/1.0 around synthetic targets. The manifest stores the seed, registry snapshot, source/licence references, schema versions, expected outcomes and a canonical SHA-256 artifact hash. When configured for the deployment, hosted artifacts also carry an Ed25519 signature that CI can verify with a pinned public key. Pro or higher API access is required to compile hosted artifacts.

curl -X POST https://ibangen.com/api/v1/fixture-manifest/compile \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "fixture_id":"checkout-de-v1",
    "seed":"checkout-ci-v1",
    "fixtures":[{"country":"DE","iban":"DE00SYNTHETIC","expected_valid":true}],
    "schemas":[{"name":"pain.001","version":"pain.001.001.09"}],
    "expected_outcomes":["valid_format"]
  }'
Read the manifest guide

Payment Scenario Compiler

GET/api/v1/payment-scenarios/catalog
POST/api/v1/payment-scenarios/compile

Business API access compiles illustrative JSON summaries with placeholder accounts and assumed payment statuses. This is not ISO 20022 XML, is not XSD-validated and cannot be imported into a bank. The placeholder IBAN is not a checksum-valid positive test fixture.

curl -X POST https://ibangen.com/api/v1/payment-scenarios/compile \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"scenario":"supplier_payment_close_name_match","country":"DE","bank_target":"Berliner Sparkasse","amount":"1250.00","currency":"EUR","vop_outcome":"CLOSE_MATCH","seed":"ci-v1"}'
Browse payment fixture families

VOP Name-Matching Benchmark

GET/api/v1/vop-benchmark/catalog
POST/api/v1/vop-benchmark/compile

Business API access can compile a deterministic matrix of synthetic legal names and controlled perturbations (case, whitespace, diacritics, aliases, punctuation, typo, different entity and missing name) with explicit expected MATCH, CLOSE_MATCH, NO_MATCH or NOAP labels. These labels are QA expectations, not a claim about any provider's live matching policy.

curl -X POST https://ibangen.com/api/v1/vop-benchmark/compile \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"seed":"release-v1","limit":50,"outcomes":["MATCH","CLOSE_MATCH","NO_MATCH","NOAP"]}'
Open the VOP lab

Bank Statement Validator

POST/api/v1/statement-validator/analyze
GET/api/v1/statement-validator/review/{review_id}
DELETE/api/v1/statement-validator/review/{review_id}
API key required Multipart upload Exactly 1 file PDF, PNG, JPG, JPEG, WEBP Max 8 MB

Upload one bank statement file and receive a structured risk review. The analyzer extracts visible fields, checks detected IBANs and supported domestic routing identifiers with deterministic validators, reviews dates/amounts/statement terminology, and returns a parseable JSON report for KYC workflows. Add expected_bank or expected_bank_slug when a statement should match a specific bank page.

cURL
curl -X POST https://ibangen.com/api/v1/statement-validator/analyze \
  -H "X-API-Key: your_api_key_here" \
  -F "statement_file=@/path/to/statement.pdf" \
  -F "expected_bank=Banco Guayaquil"
Python
import requests

with open("statement.pdf", "rb") as f:
    response = requests.post(
        "https://ibangen.com/api/v1/statement-validator/analyze",
        headers={"X-API-Key": "your_api_key_here"},
        files={"statement_file": ("statement.pdf", f, "application/pdf")},
        data={"expected_bank": "Banco Guayaquil"},
        timeout=30,
    )

print(response.status_code)
print(response.json())
JavaScript
const form = new FormData();
form.append("statement_file", fileInput.files[0]);
form.append("expected_bank", "Banco Guayaquil");

const response = await fetch("https://ibangen.com/api/v1/statement-validator/analyze", {
  method: "POST",
  headers: { "X-API-Key": "your_api_key_here" },
  body: form
});

console.log(await response.json());

If the response status is pending_analysis, poll the review endpoint until it returns completed. The alias /api/v1/statements/analyze is also available for shorter integrations. US statements return ABA routing checks in domestic_account_checks; account-number entries are format-only because no universal public account-number checksum exists.

Retention and deletion: the response includes a retention object with the configured expiry, processor, region, and encryption declaration. The source upload and review artifacts are pruned after that window; call the DELETE endpoint for earlier removal.
Pending response
{
  "success": true,
  "status": "pending_analysis",
  "review_id": "d4f7c94e7d0e4e4b9b3d9c3f1e3a9c1b",
  "review_step": "queued",
  "review_message": "Document analysis is queued.",
  "quota": {"limit": 10, "left": 9, "unlimited": false}
}
Poll for final report
curl https://ibangen.com/api/v1/statement-validator/review/d4f7c94e7d0e4e4b9b3d9c3f1e3a9c1b \
  -H "X-API-Key: your_api_key_here"
Completed response shape
{
  "success": true,
  "status": "completed",
  "score": 82,
  "risk_level": "medium",
  "is_bank_statement": true,
  "summary": "The document resembles a bank statement with verifiable IBAN evidence and some review items.",
  "extracted_fields": {
    "account_holder": "Example Customer",
    "iban": "DE89370400440532013000",
    "statement_period": "May 2026"
  },
  "iban_checks": [{
    "iban": "DE89370400440532013000",
    "valid": true,
    "country_code": "DE",
    "bank_name": "Hidden",
    "swift_code": "Hidden"
  }],
  "domestic_account_checks": [],
  "positive_signals": [],
  "risk_signals": [],
  "inconsistencies": [],
  "recommendations": []
}

AI Profile

POST/api/v1/profile
POST/api/v1/ai-profile
API key required Consumes API + profile credits Uses optimized free model pool

Generates a synthetic QA profile around an IBAN and bank context. Personal identity data is synthetic; bank names/websites use real public references when the model is confident.

cURL
curl -X POST https://ibangen.com/api/v1/profile \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "country":"Austria",
    "iban":"AT335400061166597241",
    "swift_code":"OBLAAT2LXXX",
    "bank_name":"Oberbank AG",
    "bank_city":"Linz",
    "age_min":25,
    "age_max":55
  }'
Python
import requests

payload = {
    "country": "Austria",
    "iban": "AT335400061166597241",
    "swift_code": "OBLAAT2LXXX",
    "bank_name": "Oberbank AG",
    "bank_city": "Linz",
    "age_min": 25,
    "age_max": 55,
}

response = requests.post(
    "https://ibangen.com/api/v1/profile",
    headers={"X-API-Key": "your_api_key_here"},
    json=payload,
)
print(response.json())
JavaScript
const payload = {
  country: "Austria",
  iban: "AT335400061166597241",
  swift_code: "OBLAAT2LXXX",
  bank_name: "Oberbank AG",
  bank_city: "Linz",
  age_min: 25,
  age_max: 55
};

const response = await fetch("https://ibangen.com/api/v1/profile", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here"
  },
  body: JSON.stringify(payload)
});
console.log(await response.json());
PowerShell
$headers = @{
  "Content-Type" = "application/json"
  "X-API-Key" = "your_api_key_here"
}

$body = @{
  country = "Austria"
  iban = "AT335400061166597241"
  swift_code = "OBLAAT2LXXX"
  bank_name = "Oberbank AG"
  bank_city = "Linz"
  age_min = 25
  age_max = 55
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://ibangen.com/api/v1/profile" -Method Post -Body $body -Headers $headers
PHP
 "Austria",
  "iban" => "AT335400061166597241",
  "swift_code" => "OBLAAT2LXXX",
  "bank_name" => "Oberbank AG",
  "bank_city" => "Linz",
  "age_min" => 25,
  "age_max" => 55
];
$ch = curl_init("https://ibangen.com/api/v1/profile");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => ["Content-Type: application/json", "X-API-Key: your_api_key_here"],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);
echo curl_exec($ch);
?>
{
  "success": true,
  "profile": {
    "iban": "AT335400061166597241",
    "provider": "openrouter",
    "model": "inclusionai/ling-2.6-1t:free",
    "model_tier": "free",
    "quality_score": 94,
    "quality_tier": "excellent",
    "quality_label": "Excellent synthetic QA profile",
    "profile": {
      "full_name": "Synthetic persona name",
      "country": "Austria",
      "city": "Linz",
      "bank_account": {
        "bank_name": "Oberbank AG",
        "bank_website": "https://www.oberbank.at",
        "swift_bic": "OBLAAT2LXXX"
      }
    }
  },
  "generations_left": 199
}

Quality Score

85-100

Excellent or good. Complete profile, realistic address structure, bank context, no weak placeholders.

70-84

Usable but should be reviewed. Some non-critical fields may need regeneration.

Below 70

Needs review. Paid UI should retry or avoid presenting low-quality profiles as final data.

The score is based on completeness, country consistency, bank metadata quality, weak-marker detection, and whether generated fields avoid placeholders such as N/A, 00000, and test domains.

Dataset Tools

Use these API-key endpoints when you want the same QA dataset features from automation. The `/tools` page is the browser UI; these routes are for scripts and CI jobs.

Bulk Dataset Builder

POST/api/v1/bulk-dataset

Paid only. 24h Pass: 40 rows. Starter: 500 rows. Pro/Enterprise: 10,000 rows. Supports JSON/CSV and optional AI profiles.

Test Case Generator

POST/api/v1/test-cases

Generates valid and invalid IBAN edge cases: checksum, wrong length, malformed, and country mismatch scenarios. Free users get preview-sized batches.

cURL
curl -X POST https://ibangen.com/api/v1/bulk-dataset \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"country":"Germany","quantity":100,"output":"json","include_profiles":false}'

curl -X POST https://ibangen.com/api/v1/test-cases \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{"country":"Germany","quantity":25,"output":"json"}'
Python
import requests

headers = {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here",
}

dataset = requests.post(
    "https://ibangen.com/api/v1/bulk-dataset",
    headers=headers,
    json={"country": "Germany", "quantity": 100, "output": "json"},
)

cases = requests.post(
    "https://ibangen.com/api/v1/test-cases",
    headers=headers,
    json={"country": "Germany", "quantity": 25, "output": "json"},
)

print(dataset.json())
print(cases.json())
JavaScript
const headers = {
  "Content-Type": "application/json",
  "X-API-Key": "your_api_key_here"
};

const dataset = await fetch("https://ibangen.com/api/v1/bulk-dataset", {
  method: "POST",
  headers,
  body: JSON.stringify({ country: "Germany", quantity: 100, output: "json" })
});

const cases = await fetch("https://ibangen.com/api/v1/test-cases", {
  method: "POST",
  headers,
  body: JSON.stringify({ country: "Germany", quantity: 25, output: "json" })
});

console.log(await dataset.json());
console.log(await cases.json());

Errors

Status Meaning Typical response
401 Missing or invalid API key. {"error":"Invalid API key"}
400 Invalid country, quantity, or request body. {"error":"Invalid country"}
429 API call credits exhausted. {"error":"API call limit reached"}
403 Profile generation credits exhausted. {"error":"generation_limit_reached"}
402 Paid or 24h Pass access required for a dataset tool. {"error":"bulk_dataset_requires_paid_access"}