Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "batch_validate_iban", "check_compliance" and "validate_iban"
⟨701 unchanged words⟩ BE, SK, CZ, BG, CH, LI, SM, ME andSM;RS; settlement-grade) | curated_map (our maintained bank-code map ⟨2599 unchanged words⟩
⟨674 unchanged words⟩ BE, SK, CZ, BG, CH, LI, SM, ME andSM;RS; settlement-grade) | curated_map (our maintained bank-code map ⟨2993 unchanged words⟩
⟨674 unchanged words⟩ BE, SK, CZ, BG, CH, LI, SM, ME andSM;RS; settlement-grade) | curated_map (our maintained bank-code map ⟨2592 unchanged words⟩
Authorization not required
Authorization not required
Authorization not required
Changed the definition of "batch_validate_iban", "check_compliance", "check_postal_address" and 7 more
⟨147 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨282 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25
Authorization not required
Changed the definition of "batch_validate_iban", "check_compliance" and "validate_iban"
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}Authorization not required
Authorization not required
Certificate changed, valid to 2026-12-30
Authorization not required
Certificate changed, valid to 2026-12-28
Authorization not required
Authorization not required
Changed the definition of "batch_validate_iban", "check_compliance", "lookup_bic" and 1 more
⟨2705 unchanged words⟩ the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":[" ⟨238 unchanged words⟩
⟨3077 unchanged words⟩ the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable
Changed the definition of "batch_validate_iban", "check_compliance", "lookup_bic" and 1 more
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}Authorization not required
Changed the definition of "batch_validate_iban", "check_compliance", "check_postal_address" and 8 more
⟨103 unchanged words⟩ : $0.002 USDC per IBAN via x402 (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
Changed the definition of "batch_validate_iban", "check_compliance", "lookup_bic" and 2 more
Validate up to 100 IBANs in a single call. Paid per callatin USDC via x402, it costs $0.002 per IBAN(60%insteadcheaperofthan$0.005callingper validate_ibanrepeatedlycall;aton$0.005).an API key or a credit pack each IBAN uses one request or credit, the same as one validate_iban call.
Authorization not required
Changed the definition of "batch_validate_iban", "check_compliance" and "validate_iban"
⟨458 unchanged words⟩ national register was consulted about the BANK CODE.InSanSwitzerlandMarino is where theregistertwoconfirmspart: thecodepairingwhileis theBICsupervisor’s,stillthecomes
Authorization not required
Authorization not required
Added "poll_api_key" and "request_api_key"; changed the definition of "batch_validate_iban", "check_compliance", "check_postal_address" and 5 more (9 tools before, 11 now)
⟨89 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid"],"type":"object"},{"type":"null"}]},"cost_usdc":{"description":"What THIS IBAN was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"iban":{"type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price per IBAN on the paid REST/x402 route.","type":"number"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}Authorization not required
Certificate recorded, valid to 2026-10-31
Authorization not required
First tool surface recorded: 9 tools (server version 1.5.0)
Showing the latest 28 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨280 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨79 unchanged words⟩ S) or still COMBINED (type K):thetypestandardKremovedhastypenotKbeenonpermitted since 21.11.2025, and the banksstopguaranteeprocessingpaymentpaymentsofbuiltaontypeitKfromQR-bill14.11.2026.only until the end of September 2026. DO NOT USE to learn which bank holds ⟨114 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨344 unchanged words⟩ every present address is structured (type S). The name is kept for compatibility and is not a deadline:whattype K has not been permitted since 21.11.2025, and the banksrequireguaranteefrompayment14.11.2026.of a type K QR-bill only until the end of September 2026.","type":"boolean"},"reference":{ ⟨295 unchanged words⟩
⟨288 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨171 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨104 unchanged words⟩ hand it to your human immediately together with`config_line`;`config_line`, or the header "Authorization: Bearer <key>" for the hosted server; `access_denied` means somebody refused — tell your human ⟨66 unchanged words⟩
Start the process that givesthis sessionyouritshumanowna free IBANforge API key, without any e-mailaddressaddress.andThewithoutkeyleavingdoes not unlock this session: it works once yourconversation.human puts it in the MCP client configuration and reconnects, or sends it to the REST API, so tell them where it goes when you hand it over: `config_line` (returned by poll_api_key) for Claude Code with the npm package; for the hosted server https://api.ibanforge.com/mcp, the header "Authorization: Bearer <key>", which Claude and Claude Desktop take under Request headers when the custom connector is added; ChatGPT sends no key to a connector, so in ChatGPT the key serves on the REST API only. USE WHEN: you used up the free allowance, a call answers 402, oryouyourarehuman is about to run more than a handful of ⟨132 unchanged words⟩
⟨854 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
⟨415 unchanged words⟩ POST https://api.ibanforge.com/v1/keys/generate with no body for 25 calls/month, on the RESTcalls/monthAPI or on this transport, and POST /v1/keys/claim lifts that same key to 200 amonthmonth. Send the key here as Authorization: Bearer ifk_… (or X-API-Key) and each call counts against it exactly as on the REST API).
after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN), ES (DC) and DE (the account-number check digit, by the method the Bundesbank lists for the bank code), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere. In DE it is not_checked when the bank code is not in the Bundesbank file or its method is not checked here, and not_applicable when the bank uses no check digit (method 09); national_check_digits.verified_by says whether a German verdict rests on the Bundesbank test numbers or on an independent implementation only. pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM, ES or DE (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN), de_pruefziffer (DE: the check digit of the 10-digit account number, computed by the method the Deutsche Bundesbank lists for the bank code in its Bankleitzahlendatei, named in method; the IBAN check digits already cover the whole BBAN, this says whether that bank could have issued the account number). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable: a BBAN without the national layout, which a valid IBAN never has, or in DE a bank that uses no check digit (method 09) or a method that defines none for that range of account numbers. not_checked (DE only): the check did not run on our side, because the bank code is not in the Bundesbank file or its method is not checked here (method 44, and methods no bank uses); it says nothing about the beneficiary. verified_by (DE only, whenever the method ran): bundesbank_test_numbers (the method gives the expected answer on every test number and worked example the Bundesbank publishes; a fail adds the blocking step national_check_digits_failed) or independent_implementation (the Bundesbank publishes no test number for the method, which was verified against an independent implementation only; a fail adds the warning step national_check_digits_suspect and never stops a payment). detail, present on fail, not_applicable and not_checked, says which digits disagree or why nothing was checked; it never gives the expected key. In DE the block also carries method (the Bundesbank method code), verified_by, source (with the credit line the Bundesbank asks for) and table_fetched_on (the day the method table was read). checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail, not_applicable and not_checked.","type":"string"},"method":{"description":"DE only: the Bundesbank check-digit method code of the bank code.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc | de_pruefziffer","type":"string"},"source":{"description":"DE only: the source, with the credit line the Bundesbank asks for.","type":"string"},"status":{"description":"pass | fail | not_applicable | not_checked","type":"string"},"table_fetched_on":{"description":"DE only: the day the method table was read (YYYY-MM-DD).","type":"string"},"verified_by":{"description":"DE only: bundesbank_test_numbers (a fail is blocking) | independent_implementation (a fail is a warning, national_check_digits_suspect).","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"listed_in_epc_registers":{"description":"At least one of the three schemes lists the bank; null when the EPC registers were not consulted (screened false). Outside the SEPA area the country answers (false) whether or not the registers are loaded.","type":["boolean","null"]},"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"description":"False also when no bank was screened: read institution_listed.","type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"institution_listed":{"description":"Whether the payee's BANK is on a sanctions list: bank_sanctioned when a bank was screened against every list this service names, null otherwise (never false without a screen).","type":["boolean","null"]},"matched_lists":{"items":{"type":"string"},"type":"array"},"payee_screened":{"description":"Always false: the payee (account holder) is never screened here.","type":"boolean"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN), ES (DC) and DE (the account-number check digit, by the method the Bundesbank lists for the bank code), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere. In DE it is not_checked when the bank code is not in the Bundesbank file or its method is not checked here, and not_applicable when the bank uses no check digit (method 09); national_check_digits.verified_by says whether a German verdict rests on the Bundesbank test numbers or on an independent implementation only. pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"listed_in_epc_registers":{"description":"At least one of the three schemes lists the bank; null when the EPC registers were not consulted (screened false). Outside the SEPA area the country answers (false) whether or not the registers are loaded.","type":["boolean","null"]},"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"description":"False also when no bank was screened: read institution_listed.","type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"institution_listed":{"description":"Whether the payee's BANK is on a sanctions list: bank_sanctioned when a bank was screened against every list this service names, null otherwise (never false without a screen).","type":["boolean","null"]},"matched_lists":{"items":{"type":"string"},"type":"array"},"payee_screened":{"description":"Always false: the payee (account holder) is never screened here.","type":"boolean"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM, ES or DE (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN), de_pruefziffer (DE: the check digit of the 10-digit account number, computed by the method the Deutsche Bundesbank lists for the bank code in its Bankleitzahlendatei, named in method; the IBAN check digits already cover the whole BBAN, this says whether that bank could have issued the account number). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable: a BBAN without the national layout, which a valid IBAN never has, or in DE a bank that uses no check digit (method 09) or a method that defines none for that range of account numbers. not_checked (DE only): the check did not run on our side, because the bank code is not in the Bundesbank file or its method is not checked here (method 44, and methods no bank uses); it says nothing about the beneficiary. verified_by (DE only, whenever the method ran): bundesbank_test_numbers (the method gives the expected answer on every test number and worked example the Bundesbank publishes; a fail adds the blocking step national_check_digits_failed) or independent_implementation (the Bundesbank publishes no test number for the method, which was verified against an independent implementation only; a fail adds the warning step national_check_digits_suspect and never stops a payment). detail, present on fail, not_applicable and not_checked, says which digits disagree or why nothing was checked; it never gives the expected key. In DE the block also carries method (the Bundesbank method code), verified_by, source (with the credit line the Bundesbank asks for) and table_fetched_on (the day the method table was read). checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail, not_applicable and not_checked.","type":"string"},"method":{"description":"DE only: the Bundesbank check-digit method code of the bank code.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc | de_pruefziffer","type":"string"},"source":{"description":"DE only: the source, with the credit line the Bundesbank asks for.","type":"string"},"status":{"description":"pass | fail | not_applicable | not_checked","type":"string"},"table_fetched_on":{"description":"DE only: the day the method table was read (YYYY-MM-DD).","type":"string"},"verified_by":{"description":"DE only: bundesbank_test_numbers (a fail is blocking) | independent_implementation (a fail is a warning, national_check_digits_suspect).","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}⟨221 unchanged words⟩ { country, scheme, status: pass | fail | not_applicable | not_checked, detail?, method?, verified_by? } (FR, MC, BE, IT, SM, ES andESDE only): the national key inside the BBAN; ⟨7 unchanged words⟩ been issued as written, and valid staystrue.true; in DE a fail with verified_by independent_implementation is a warning (national_check_digits_suspect), not a stop, and not_checked means the bank code or its Bundesbank method is not covered here. valid (boolean), bank_code_holder, checks, country ⟨579 unchanged words⟩
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN), ES (DC) and DE (the account-number check digit, by the method the Bundesbank lists for the bank code), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere. In DE it is not_checked when the bank code is not in the Bundesbank file or its method is not checked here, and not_applicable when the bank uses no check digit (method 09); national_check_digits.verified_by says whether a German verdict rests on the Bundesbank test numbers or on an independent implementation only. pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM, ES or DE (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN), de_pruefziffer (DE: the check digit of the 10-digit account number, computed by the method the Deutsche Bundesbank lists for the bank code in its Bankleitzahlendatei, named in method; the IBAN check digits already cover the whole BBAN, this says whether that bank could have issued the account number). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable: a BBAN without the national layout, which a valid IBAN never has, or in DE a bank that uses no check digit (method 09) or a method that defines none for that range of account numbers. not_checked (DE only): the check did not run on our side, because the bank code is not in the Bundesbank file or its method is not checked here (method 44, and methods no bank uses); it says nothing about the beneficiary. verified_by (DE only, whenever the method ran): bundesbank_test_numbers (the method gives the expected answer on every test number and worked example the Bundesbank publishes; a fail adds the blocking step national_check_digits_failed) or independent_implementation (the Bundesbank publishes no test number for the method, which was verified against an independent implementation only; a fail adds the warning step national_check_digits_suspect and never stops a payment). detail, present on fail, not_applicable and not_checked, says which digits disagree or why nothing was checked; it never gives the expected key. In DE the block also carries method (the Bundesbank method code), verified_by, source (with the credit line the Bundesbank asks for) and table_fetched_on (the day the method table was read). checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail, not_applicable and not_checked.","type":"string"},"method":{"description":"DE only: the Bundesbank check-digit method code of the bank code.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc | de_pruefziffer","type":"string"},"source":{"description":"DE only: the source, with the credit line the Bundesbank asks for.","type":"string"},"status":{"description":"pass | fail | not_applicable | not_checked","type":"string"},"table_fetched_on":{"description":"DE only: the day the method table was read (YYYY-MM-DD).","type":"string"},"verified_by":{"description":"DE only: bundesbank_test_numbers (a fail is blocking) | independent_implementation (a fail is a warning, national_check_digits_suspect).","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}⟨310 unchanged words⟩ "type":["boolean","null"]},"note":{"description":"Present only when found is false and the part of the directory served from a private file (EBA STEP2, NBP and OeNB records) is not loaded on this deployment: the absence was not looked up there.","type":"string"},"source":{"description":"Code of the dataset ⟨161 unchanged words⟩
⟨2678 unchanged words⟩ the registers are not loaded on this deployment, or no bank was resolved because the bank-code check itself is unavailable (not consulted, never read as not_listed or no_bank). Absent outside SEPA.","type":[" ⟨231 unchanged words⟩
after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment (not consulted, never read as not_listed). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}⟨172 unchanged words⟩ (e.g. sanctioned_country, fatf_grey_list, emi_issuer, no_vop). compliance.sanctions.institution_listed says whether the payee's bank is on a list (null when no bank was screened, where bank_sanctioned still answers false) and payee_screened is always false; compliance.reachability.listed_in_epc_registers and compliance.vop.register_status name the registers' answers, null when not consulted (screened false); outside the SEPA area the country answers (false, not_listed) whether or not the registers are loaded. The flag bank_code_inferred carries no weight. COST: $0.02 per call (free with no ⟨57 unchanged words⟩
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"matched_lists":{"items":{"type":"string"},"type":"array"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"listed_in_epc_registers":{"description":"At least one of the three schemes lists the bank; null when the EPC registers were not consulted (screened false). Outside the SEPA area the country answers (false) whether or not the registers are loaded.","type":["boolean","null"]},"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"description":"False also when no bank was screened: read institution_listed.","type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"institution_listed":{"description":"Whether the payee's BANK is on a sanctions list: bank_sanctioned when a bank was screened against every list this service names, null otherwise (never false without a screen).","type":["boolean","null"]},"matched_lists":{"items":{"type":"string"},"type":"array"},"payee_screened":{"description":"Always false: the payee (account holder) is never screened here.","type":"boolean"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment (not consulted, never read as not_listed). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}⟨110 unchanged words⟩ of the rows carry an LEI from GLEIF. SOURCE: source names the dataset of this row and source_name spells it out; source_as_of is present only when that dataset is a copy frozen at that month (the public copy of the SWIFT directory, frozen in January 2018). listed_in_current_source says whether this BIC8 still appears in a list refreshed this cycle (GLEIF, a national register, the EPC scheme registers, the EBA STEP2 and NBP lists): true when one of them carries it, null when it was not found in what could be read in full. It never answers false today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, which can drop a BIC they carry, so an absence is not proven. It does not prove the bank still exists under this name. COST: $0.003 per call (free with no ⟨57 unchanged words⟩
⟨38 unchanged words⟩ "string","null"]},"city":{"description":"Null, never an empty string, when the source leaves the town blank.","type":["string","null"]},"country ⟨3 unchanged words⟩ Same shape as REST GET /v1/bic/:code. name is the row's country name, then the ISO name, and falls back to the country codewhen the rowonlycarrieswhennoneithername.exists.","properties":{"code":{"type": ⟨29 unchanged words⟩ no earlier than 2027-01-01. Use country.name, whichfallsisbacknevertonull: thecoderow'srathercountrythanname,toelsenull.the ISO name, else the code.","type":["string","null"]},"error":{"type":"string"},"found":{"description":"True only when the row names an institution: a record is complete or not found.","type":"boolean"},"institution":{"description" ⟨19 unchanged words⟩ ["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"source":{"description":"Code of the dataset this row comes from.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present only for a frozen copy.","type":"string"},"source_name":{"description":"source names the dataset of this row and source_name spells it out; source_as_of is present only when that dataset is a copy frozen at that month. listed_in_current_source says whether this BIC8 still appears in a list refreshed this cycle (GLEIF, a national register, the EPC scheme registers, the EBA STEP2 and NBP lists): true when one of them carries it, null when it was not found in what could be read in full. It never answers false today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, which can drop a BIC they carry, so an absence is not proven. It does not prove the bank still exists under this name.","type":["string","null"]}," ⟨18 unchanged words⟩
⟨136 unchanged words⟩ risk), or check SEPA reachability. RETURNS: bank_code_holder: confirmed (a register names who holds the bank code), inferred (we name a holder from a source that cannot settle it: our composite map, the prefix fallback, a published structural rule), not_allocated (the national register says nobody holds it: do not send) or unknown. valid stays true in all four: it only means the IBAN is well formed. checks: one status per check (pass, fail, inferred, unknown, not_checked, not_applicable); payee_name, account_exists and payee_sanctions are always not_checked. national_check_digits { country, scheme, status: pass | fail, detail? } (FR, MC, BE, IT, SM and ES only): the national key inside the BBAN; fail means the account number cannot have been issued as written, and valid stays true. valid (boolean), bank_code_holder, checks, country { code, name }, bic { ⟨4 unchanged words⟩ city, basis, authoritative, source, as_of, source_as_of?, listed_in_current_source, lei, lei_status, address { street, post_code, ⟨246 unchanged words⟩ listed as ready in the EPC VoP register, bank_reachability, bank_schemes, vop_register_status: the bank itself in the EPC registers, never the country }, risk_indicators { issuer_type (null when no ⟨288 unchanged words⟩
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when a register says the code is leaving (DE, authoritative) or has been struck off (IT, authoritative false, with retired_on). Still a verified result: it WAS allocated. Never a refusal.","type":"boolean"},"retired_on":{"description":"YYYY-MM-DD, with retired where the register dates it (IT): the last day it lists this code for its last holder.","type":"string"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. DE: the successor the register designates, re-paper against it. IT: the legal successor by merger or incorporation, not necessarily the bank now holding the account.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bank_code_holder":{"description":"confirmed | inferred | not_allocated | unknown. Who holds the bank code. confirmed: a register that publishes holders names the holder of this code (a national register that settles the code space, or a partial register on a hit). inferred: we name a holder from a source that cannot settle it (our composite map, the prefix fallback, a published structural rule), so read it as our inference. not_allocated: the national register says nobody holds this code, so do not send. unknown: no conclusion. valid stays true in all four: it only means the IBAN is well formed. bank_code_check.status verified means resolved; this field says whether a source settles it.","type":"string"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"listed_in_current_source":{"description":"Whether this BIC8 still appears in a list refreshed this cycle: GLEIF, the directory sources that carry no vintage, a national register, the EPC scheme registers. true when one of them carries it; null when it was not found in what could be read in full (never false by default). false is reserved for an index built from every list read in full, which is not the case today: the EBA STEP2 and NBP lists are only read through our deduplicated directory, so this field answers true or null. It does NOT prove the bank still exists under this name: a clearing list can keep the name of a bank that was absorbed.","type":["boolean","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the source DATA is from, present ONLY when it differs from as_of. On a curated_map or directory_prefix answer it dates the directory row that supplied the name, the city, the LEI or the address when that row comes from a frozen public copy; never present on a national_register answer, whose name comes from the register and is dated by as_of. Absent means no gap has been established, never 'this is current'.","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"checks":{"additionalProperties":false,"description":"One status per check: pass (checked against a source that settles it), fail (checked, and wrong), inferred (answered from a source that does not settle it), unknown (attempted, no conclusion), not_checked (IBANforge does not make this check here), not_applicable (the check has no object for this IBAN). payee_name: never checked here; the name check is made by the payee's bank through Verification of Payee (VoP), and sepa.vop_register_status says whether that bank answers VoP requests. account_exists: never checked here; only the payee's bank knows whether the account is open. payee_sanctions: never checked; the sanctions screen of POST /v1/iban/compliance is made on the payee's bank (BIC8) and country only. institution_sanctions and country_sanctions are filled by POST /v1/iban/compliance and not_checked on a validation. national_check_digits: the check key a country keeps inside the BBAN, a second check independent of mod-97. Checked for FR and MC (RIB key), BE (the last two digits, modulo 97), IT and SM (CIN) and ES (DC), with the proof in the national_check_digits block, and for GB (Vocalink modulus), with the proof in modulus_check; not_checked elsewhere (the German account-number methods are not checked yet). pass means the account number is well formed, never that the account exists; fail means it cannot have been issued as written, and valid stays true. A key may be added later; a key is never removed. Present only when valid is true.","properties":{"account_exists":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bank_code":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"bic":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"country_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_checksum":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"iban_structure":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"institution_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"national_check_digits":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_name":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"payee_sanctions":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"},"sepa_reachability":{"description":"pass | fail | inferred | unknown | not_checked | not_applicable","type":"string"}},"required":["iban_structure","iban_checksum","bank_code","bic","sepa_reachability","national_check_digits","account_exists","payee_name","institution_sanctions","country_sanctions","payee_sanctions"],"type":"object"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"national_check_digits":{"additionalProperties":false,"description":"The check key a country keeps inside the BBAN, recomputed from the IBAN alone. Present only on a valid IBAN of FR, MC, BE, IT, SM or ES (GB has modulus_check instead); absent elsewhere, where checks.national_check_digits is not_checked. country is the IBAN country. scheme names the algorithm: fr_rib_key (FR and MC: the RIB key, the last two digits of the BBAN, over the bank code, branch code and account number), be_mod97 (BE: the last two digits, the first ten digits modulo 97, or 97 when the remainder is 0), it_cin (IT and SM: the CIN, the control letter at the start of the BBAN, over the ABI, CAB and account number), es_dc (ES: the two DC digits, positions 9 and 10 of the BBAN). status: pass (the key matches, so the account number is well formed; it does not prove the account exists or is open) or fail (the key does not match: this account number cannot have been issued as written, a typo or a made-up number). A fail never makes valid false, because the IBAN check digits are right: read the two separately, and confirm the details with the beneficiary before paying. not_applicable is reserved for a BBAN without the national layout, which a valid IBAN never has. detail, present on fail and not_applicable only, says which digits disagree; it never gives the expected key. checks.national_check_digits repeats status.","properties":{"country":{"description":"The IBAN country (MC stays MC, SM stays SM).","type":"string"},"detail":{"description":"Present on fail and not_applicable only.","type":"string"},"scheme":{"description":"fr_rib_key | be_mod97 | it_cin | es_dc","type":"string"},"status":{"description":"pass | fail | not_applicable","type":"string"}},"required":["country","scheme","status"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"bank_reachability":{"description":"listed | not_listed | no_bank | bank_code_not_allocated, or null. Whether the EPC scheme registers list the resolved BANK, never borrowed from the country (member, schemes and basis still describe the country and are unchanged). listed: the bank has rows in the SCT, SCT Inst or SDD register. not_listed: it has none (an absence from the register is not an exclusion from the scheme). no_bank: no BIC resolved for this bank code, so no bank could be looked up in the EPC registers (a register may still name the holder: see bank_code_holder and bank_code_check). bank_code_not_allocated: the national register says nobody holds the bank code. null: the registers are not loaded on this deployment (not consulted, never read as not_listed). Absent outside SEPA.","type":["string","null"]},"bank_schemes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"The bank's own schemes from the EPC registers when bank_reachability is listed; [] for an unallocated bank code; null otherwise."},"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_register_status":{"description":"active | pending | inactive | not_listed, or null. The bank's status in the EPC Verification of Payee register: active (the same as vop_participant true), pending, inactive, or not_listed when the register has no row for it; null when no BIC resolved or the register was not consulted (screened false). Outside the SEPA area the country answers instead of the register (not_listed on POST /v1/iban/compliance) whether or not the register is loaded; the validation carries no sepa.vop_register_status there. It says whether the payee's bank answers VoP requests; IBANforge never runs the name check itself.","type":["string","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today CH, LI, DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}⟨176 unchanged words⟩ no_vop). COST: $0.02 per call (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today CH, LI, DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"matched_lists":{"items":{"type":"string"},"type":"array"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"matched_lists":{"items":{"type":"string"},"type":"array"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}⟨236 unchanged words⟩ $0 per call, on every surface (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
⟨180 unchanged words⟩ $0 per call, on every surface (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
⟨116 unchanged words⟩ from GLEIF. COST: $0.003 per call (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
⟨127 unchanged words⟩ LI accounts. COST: $0.003 per call (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
⟨177 unchanged words⟩ is free and does NOT count against thedaily free-tierfreelimit.allowance.
⟨18 unchanged words⟩ without leaving your conversation. USE WHEN: youhitusedtheupdailythe free allowance, a call answers 402, or ⟨123 unchanged words⟩ is free and does NOT count against thedaily free-tierfreelimitallowance — it works even after thelimitallowance isreached.spent.
⟨63 unchanged words⟩ is free and does NOT count against thedaily free-tierfreelimitallowance — it works even after thelimitallowance isreached.spent. A human reads every report; verified data errors ⟨7 unchanged words⟩
⟨529 unchanged words⟩ worth. Only where authoritative is true (todayCHDEandagainstLIthe Deutsche Bundesbank Bankleitzahlendatei, AT against theSIXOesterreichischeBankMasterNationalbank SEPA-Zahlungsverkehrs-Verzeichnis,DEBE against theBundesbankBanqueBankleitzahlendateinationale de Belgique bank identification codes,ATSK against theOeNBNárodnáregisterbanka Slovenska prevodník of identification codes for the domestic payment system,BECZ against theNBBČeskáregisternárodní banka číselník of payment-system codes (Číselník kódů platebního styku), BG against theBNBBulgarian National Bank BAE register, andSKCHagainstandtheLINárodnáagainstbankatheSlovenskaSIXprevodníkBankMaster) does not_in_register mean the bank code is ⟨33 unchanged words⟩ different institution. COST: $0.005 per call (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today CH, LI, DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}⟨371 unchanged words⟩ $0 per call, on every surface (free:10withunits/IP/dayno key on this transport: 25 units a week per source address, one per call and one per IBAN in batch_validate_iban,orreset on Monday 00:00 UTC. Or an ifk_ key with no e-mail at all—: POST https://api.ibanforge.com/v1/keys/generate with no body for 25 ⟨14 unchanged words⟩
Run afullpre-flight compliancechecktriage on an IBAN before sending a SEPA / ⟨16 unchanged words⟩ and wants to triage risk first, asks"iswhetherthistheIBANpayee'ssafebanktoorpay?",itsaskscountryforissanctionsunderscreeningsanctions, asks if a SEPA Instant transferwillcansucceedreach the bank, or needs a numeric risk score for ⟨19 unchanged words⟩ or ComplyAdvantage. CHECKS: IBAN validity + sanctions lists (OFAC, EU, UN) matched on the payee's bank (BIC8), the country checked against a fixed list of sanctioned jurisdictions, never the payee's name + FATFjurisdictions)status + SEPA Instant reachability +VoPwhether(EUthe2024/886EPC Verification of Payee (VoP)participant.register lists the bank as ready; the name check itself is done by the payee's bank, never here. RETURNS: the full validate enrichment plus a ⟨76 unchanged words⟩
⟨1295 unchanged words⟩ ":"string"},"sources":{"type":["string","null"]}},"required":["scope","disclaimer"] ⟨528 unchanged words⟩
⟨65 unchanged words⟩ resolves the BIC for you. BACKED BY: BIC directory, 121,000+BICentries (39entries,000+LEI-enrichednotviainstitutions):GLEIF;GLEIFadditionalandrowsnationalfromregisters,SwiftCodesrefreshed(MIT)monthly,Bundesbank,plusSIX,aNBP,publicEBAcopyStep2ofSCT)the SWIFT directory frozen in January 2018 that still makes up about two thirds of the rows. 39,000+refreshedofmonthly.the rows carry an LEI from GLEIF. COST: $0.003 per call (free: 10 ⟨45 unchanged words⟩
⟨57 unchanged words⟩ (bank vs PFS vs SIC-only participant).THE DEEPEST SWISSEVERYCLEARINGIIDDATAOFINTHEANYSIXPUBLICBANKMASTER,APIwith—its fullSIX BankMasterpayment-rail participation (SIC, RTGS CHF, Instant ⟨101 unchanged words⟩
Verify whetheraanEuropeanIBAN from any of the 89 IBAN countries is valid AND enrich it with bank, ⟨647 unchanged words⟩
⟨431 unchanged words⟩ national register was consulted about the BANK CODE.InSanSwitzerlandMarino is where theregistertwoconfirmspart: thecodepairingwhileis theBICsupervisor’s,stillthecomescodefromspaceouriscuratednotmap.its to settle.","type":"boolean"},"bank_name":{ ⟨28 unchanged words⟩ this BIC for this bank code — today CH, LI, DE, AT, BE, BG, SK and ⟨53 unchanged words⟩ routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null" ⟨71 unchanged words⟩ "},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name", ⟨1010 unchanged words⟩
⟨139 unchanged words⟩ code, name }, bic { code, bic8, redirected_from?, bank_name, city, basis, authoritative, source, as_of ⟨53 unchanged words⟩ , confirm it before it becomes a routinginstructioninstruction. code is 8 or 11 characters, as the consulted source publishes it: COMPARE A SUPPLIED BIC ON bic8, never on code — the branch code is informational and in a cooperative network it names the LOCAL bank while the first eight name its clearing institution (Swiss IID 30020 is RBABCH22180, Crédit Mutuel de la Vallée SA, while RBABCH22 alone is Entris Banking AG). redirected_from is present when the register answered for the bank code that took over the one you asked about (CH/LI: SIX redirects a concatenated IID, which does not make the IBAN invalid) — lei and address are read from the same ⟨213 unchanged words⟩ CH and LI against the SIX BankMaster,andDE against the Bundesbank Bankleitzahlendatei, AT against the OeNB register, BE against the NBB register, BG against the BNB BAE register and SK against the Národná banka Slovenska prevodník) does not_in_register mean the bank code is ⟨86 unchanged words⟩
⟨431 unchanged words⟩ national register was consulted about the BANK CODE.InSanSwitzerlandMarino is where theregistertwoconfirmspart: thecodepairingwhileis theBICsupervisor’s,stillthecomescodefromspaceouriscuratednotmap.its to settle.","type":"boolean"},"bank_name":{ ⟨28 unchanged words⟩ this BIC for this bank code — today CH, LI, DE, AT, BE, BG, SK and ⟨53 unchanged words⟩ routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null" ⟨71 unchanged words⟩ "},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name", ⟨809 unchanged words⟩
after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"count":{"description":"Number of IBANs processed.","type":"number"},"results":{"description":"One result per input IBAN, in the same order. Same shape as validate_iban.","items":{"additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"},"type":"array"}},"required":["results","count"],"type":"object"}⟨146 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"matched_lists":{"items":{"type":"string"},"type":"array"}},"required":["country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"status":{"type":"string"}},"required":["participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"iban":{"type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":"string"}},"required":["scope","disclaimer"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","compliance","meta","cost_usdc"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"compliance":{"additionalProperties":false,"properties":{"flags":{"items":{"type":"string"},"type":"array"},"reachability":{"additionalProperties":false,"properties":{"screened":{"type":"boolean"},"sct":{"type":"boolean"},"sdd":{"type":"boolean"},"sepa_instant":{"type":"boolean"}},"required":["screened","sepa_instant","sct","sdd"],"type":"object"},"risk_level":{"description":"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one.","type":"string"},"risk_score":{"anyOf":[{"maximum":100,"minimum":0,"type":"number"},{"type":"null"}],"description":"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."},"sanctions":{"additionalProperties":false,"properties":{"bank_sanctioned":{"type":"boolean"},"bank_screened":{"description":"False means no bank was screened; do not interpret bank_sanctioned as a finding.","type":"boolean"},"country_sanctioned":{"type":"boolean"},"fatf_status":{"type":"string"},"matched_lists":{"items":{"type":"string"},"type":"array"}},"required":["bank_screened","country_sanctioned","bank_sanctioned","matched_lists","fatf_status"],"type":"object"},"vop":{"additionalProperties":false,"properties":{"participant":{"type":"boolean"},"screened":{"type":"boolean"},"status":{"type":"string"}},"required":["screened","participant","status"],"type":"object"}},"required":["sanctions","reachability","vop","risk_score","risk_level","flags"],"type":"object"},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"meta":{"additionalProperties":{},"properties":{"disclaimer":{"type":"string"},"fatf_as_of":{"type":["string","null"]},"sanctions_as_of":{"type":["string","null"]},"scope":{"type":"string"},"sources":{"type":"string"}},"required":["scope","disclaimer"],"type":"object"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc","compliance","meta"],"type":"object"}⟨251 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
⟨195 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
⟨107 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
⟨146 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
⟨500 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
before
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}],"description":"Resolved BIC/SWIFT when BBAN→BIC mapping exists. Read basis before storing it as a routing instruction: only a national_register pairing is settlement-grade."},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution","type":"string"}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"processing_ms":{"type":"number"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, BG, SK and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}⟨386 unchanged words⟩ and one per IBAN in batch_validate_iban, ora freeanAPIifk_ key with no e-mail at all — POST https://api.ibanforge.com/v1/keys/generate with no body for20025 REST calls/month, and POST /v1/keys/claim lifts that same key to 200 a month).
Collect the approved IBANforge API key — Collect the API key once a human has approved the request opened by request_api_key. USE WHEN: you have called request_api_key and shown the code to your human. HOW TO CALL IT: leave `device_code` empty to reuse the last request from this session. The server usually waits up to thirty seconds before answering, and sometimes answers at once when it is busy — either way, calling it once per minute is enough, never in a tight loop. WHAT THE ANSWERS MEAN: `authorization_pending` is normal and means nobody has approved yet — wait `retry_in_seconds` and call again; `approved` carries the key ONCE a…
Request an IBANforge API key — Start the process that gives this session its own free IBANforge API key, without any e-mail address and without leaving your conversation. USE WHEN: you hit the daily free allowance, a call answers 402, or you are about to run more than a handful of validations. WHAT YOU MUST DO WITH THE RESULT: read `status` first — `ok` means a code was issued, anything else means no code exists and `display_to_human` tells you and your human what to do instead. On `ok`, show `display_to_human` to your human VERBATIM (the user_code and the link) and say, in your own words, that opening the link and approvi…
after
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"bank_code_check":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"authoritative":{"description":"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated.","type":"boolean"},"candidates":{"description":"BIC8 the prefix matched; >1 means the BIC may belong to another institution.","type":"number"},"check_digit":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"valid":{"type":"boolean"}},"required":["valid","algorithm"],"type":"object"},"institution":{"additionalProperties":false,"properties":{"country":{"type":"string"},"lei":{"type":["string","null"]},"name":{"type":"string"},"post_code":{"type":["string","null"]},"street":{"type":["string","null"]},"town":{"type":["string","null"]}},"required":["name","street","post_code","town","country"],"type":"object"},"match":{"description":"register (exact key) | prefix (bic8 LIKE heuristic) | null","type":["string","null"]},"reason":{"description":"WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.","type":"string"},"register":{"type":["string","null"]},"retired":{"description":"True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.","type":"boolean"},"status":{"description":"verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.","type":"string"},"superseded_by":{"description":"The bank code that takes over. Re-paper the beneficiary against it.","type":"string"},"value":{"type":"string"}},"required":["value","status","match","register","authoritative","as_of"],"type":"object"},"bban":{"additionalProperties":false,"properties":{"account_number":{"type":"string"},"bank_code":{"type":"string"},"branch_code":{"type":"string"}},"required":["bank_code","account_number"],"type":"object"},"bic":{"anyOf":[{"additionalProperties":false,"properties":{"address":{"anyOf":[{"additionalProperties":false,"properties":{"as_of":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":"string"},"language":{"type":["string","null"]},"post_code":{"type":["string","null"]},"region":{"type":["string","null"]},"romanization":{"enum":["original_latin","gleif_english","unavailable"],"type":"string"},"romanized":{"type":["string","null"]},"source":{"type":"string"},"street":{"type":["string","null"]},"type":{"const":"registered","type":"string"}},"required":["type","street","post_code","region","city","country","romanized","romanization","source","language","as_of"],"type":"object"},{"type":"null"}]},"as_of":{"type":["string","null"]},"authoritative":{"description":"Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. San Marino is where the two part: the pairing is the supervisor’s, the code space is not its to settle.","type":"boolean"},"bank_name":{"type":["string","null"]},"basis":{"description":"Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE, SK, CZ, BG, CH, LI and SM; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.","type":"string"},"bic8":{"description":"The eight characters of the institution — the field to compare a supplied BIC against. code is served as the consulted source publishes it, so it is 8 or 11 characters; this one never moves. The branch code (last three characters) is informational: in a cooperative network it names the LOCAL bank and the first eight its clearing institution.","type":"string"},"city":{"type":["string","null"]},"code":{"type":"string"},"lei":{"description":"GLEIF identity of the resolved BIC holder, not necessarily the bank-code holder.","type":["string","null"]},"lei_status":{"type":["string","null"]},"postal_address":{"anyOf":[{"additionalProperties":false,"properties":{"adr_line":{"items":{"type":"string"},"type":"array"},"as_of":{"type":["string","null"]},"bldg_nb":{"type":"string"},"ctry":{"type":"string"},"format":{"enum":["structured","hybrid"],"type":"string"},"pst_cd":{"type":"string"},"source":{"type":"string"},"strt_nm":{"type":"string"},"twn_nm":{"type":"string"}},"required":["twn_nm","ctry","format","source","as_of"],"type":"object"},{"type":"null"}]},"redirected_from":{"description":"The bank code asked about, when the register answered for the one that took over its clearing (CH/LI only today: SIX marks an IID concatenated and publishes its successor). The IBAN stays valid — a redirect is not a retirement.","type":"string"},"source":{"description":"Source of the bank-code/BIC pairing; keep its provenance.","type":["string","null"]},"source_as_of":{"description":"Year-month the SOURCE DATA is from, present only when it differs from as_of. as_of dates the import; for the redistributed SWIFT directory the upstream stopped publishing years ago, so as_of alone presents an old bank name as last month's. Absent means no gap has been established, never \"this is current\".","type":"string"}},"required":["code","bank_name","city"],"type":"object"},{"type":"null"}]},"check_digits":{"type":"string"},"clearing":{"anyOf":[{"additionalProperties":false,"properties":{"eurosic":{"type":"boolean"},"iid":{"type":"string"},"instant_payments_chf":{"type":"boolean"},"is_qr_iid":{"type":"boolean"},"name":{"type":"string"},"qr_iid":{"type":["string","null"]},"qr_iid_source":{"anyOf":[{"enum":["register","headquarters"],"type":"string"},{"type":"null"}]},"qr_iids":{"items":{"type":"string"},"type":"array"},"sic":{"type":"boolean"},"town":{"type":["string","null"]},"type":{"type":"string"}},"required":["iid","name","type","town","sic","instant_payments_chf","eurosic","qr_iid","qr_iid_source"],"type":"object"},{"type":"null"}],"description":"Swiss clearing data when country is CH or LI."},"cost_usdc":{"description":"What THIS call was billed. Zero on the free MCP tier.","type":"number"},"country":{"additionalProperties":false,"properties":{"code":{"description":"ISO 3166-1 alpha-2 country code.","type":"string"},"name":{"type":"string"}},"required":["code","name"],"type":"object"},"error":{"type":"string"},"error_detail":{"type":"string"},"formatted":{"description":"IBAN with 4-char groups for display.","type":"string"},"iban":{"description":"Normalized IBAN (uppercase, no spaces).","type":"string"},"issuer":{"additionalProperties":false,"properties":{"classification":{"description":"curated | register | default. Whether the type was established or assumed. curated = the BIC8 is in the issuer set, so this is an identification. register = an official register names the holder of this bank code and says what it is; it carries a date and an authority in psd_registration, and it only ever replaces a default. default = nothing is on file and \"bank\" is the fallback, which covers 97.9% of BIC8 (measured 29/07/2026). Count curated and register when sizing virtual-IBAN exposure, never default.","type":"string"},"iban_issuer":{"enum":["confirmed","not_listed"],"type":"string"},"name":{"type":"string"},"type":{"description":"bank | digital_bank | emi | payment_institution; null when unsubstantiated","type":["string","null"]}},"required":["type","name","classification"],"type":"object"},"list_price_usdc":{"description":"Catalogue price of the same call on the paid REST/x402 route.","type":"number"},"modulus_check":{"additionalProperties":false,"properties":{"checked":{"type":"boolean"},"passed":{"type":["boolean","null"]},"source":{"type":"string"},"table_fetched_on":{"type":"string"}},"required":["checked","passed","source","table_fetched_on"],"type":"object"},"next_steps":{"description":"Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.","items":{"additionalProperties":false,"properties":{"action":{"description":"An IBANforge call that performs the step, when one exists.","type":"string"},"because":{"description":"The response field that produced this step.","type":"string"},"code":{"description":"Stable identifier. Branch on this.","type":"string"},"do":{"type":"string"}},"required":["code","do","because"],"type":"object"},"type":"array"},"official_identity":{"additionalProperties":false,"description":"Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.","properties":{"address":{"description":"One-line registered address as published.","type":["string","null"]},"as_of":{"description":"Date of the list this row came from. Both lists are republished every business day.","type":"string"},"attribution":{"description":"The Banco de Espana citation formula, verbatim. Spanish blocks only.","type":"string"},"authoritative":{"description":"Always false. Neither publisher allocates bank codes.","type":"boolean"},"category":{"type":"string"},"free_of_charge":{"description":"Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.","type":"string"},"lei":{"type":["string","null"]},"matched_by":{"description":"lei | national_code","type":"string"},"name":{"description":"The institution's name as the publisher writes it.","type":"string"},"source":{"description":"The publisher, cited as their licence requires. Relay it.","type":"string"}},"required":["name","lei","address","category","matched_by","source","free_of_charge","as_of","authoritative"],"type":"object"},"pra_authorisation":{"additionalProperties":false,"properties":{"authorised":{"const":true,"type":"boolean"},"basis":{"type":"string"},"firm_name":{"type":"string"},"frn":{"type":"string"},"list_month":{"type":"string"},"section":{"type":"string"},"source":{"type":"string"}},"required":["authorised","firm_name","frn","section","basis","source","list_month"],"type":"object"},"processing_ms":{"type":"number"},"psd_registration":{"additionalProperties":false,"properties":{"as_of":{"type":"string"},"competent_authority":{"type":"string"},"country":{"type":"string"},"entity_type":{"type":"string"},"name":{"type":"string"},"registered":{"const":true,"type":"boolean"},"source":{"type":"string"}},"required":["registered","entity_type","name","country","competent_authority","source","as_of"],"type":"object"},"risk_indicators":{"additionalProperties":false,"properties":{"country_risk":{"type":"string"},"issuer_type":{"description":"Null when no institution resolved — it no longer defaults to \"bank\".","type":["string","null"]},"sepa_reachable":{"type":"boolean"},"sepa_reachable_scope":{"description":"Scope the reachability holds at. Country-derived, not account-derived.","type":"string"},"test_bic":{"type":"boolean"},"vop_coverage":{"type":"boolean"}},"required":["issuer_type","country_risk","test_bic","sepa_reachable","sepa_reachable_scope","vop_coverage"],"type":"object"},"sepa":{"additionalProperties":false,"properties":{"basis":{"description":"Where `schemes` came from: read at the EPC register for this bank, or defaulted from the country.","enum":["country_default","epc_register"],"type":"string"},"member":{"type":"boolean"},"schemes":{"items":{"type":"string"},"type":"array"},"vop_participant":{"description":"true = resolved bank is listed as ready in the EPC VoP scheme register; null = no institution resolved, or the VoP register is not loaded (not consulted); a resolved bank outside the SEPA area is answered false from the country either way.","type":["boolean","null"]},"vop_required":{"type":"boolean"}},"required":["member","schemes","vop_required"],"type":"object"},"valid":{"type":"boolean"}},"required":["iban","valid","cost_usdc"],"type":"object"}