Valider un IBAN
Validez un IBAN unique avec verification complete du checksum, analyse de la structure BBAN specifique au pays, recherche automatique du BIC et de l'etablissement, donnees de conformite SEPA, classification de l'emetteur (banque vs. EMI/neobanque) et indicateurs de risque pour les agents de conformite. La longueur et le découpage de chaque pays, avec l'exemple officiel et le registre consulté, sont sur IBAN par pays.
Endpoint
POST https://api.ibanforge.com/v1/iban/validate
Cout : $0.005 USDC par requete
Requete
En-tetes
| En-tete | Valeur | Requis |
|---|---|---|
Content-Type | application/json | Oui |
Authorization | Bearer ifk_... (clé API gratuite) | L'un des deux |
X-PAYMENT | Token de paiement x402 | L'un des deux |
Corps
{
"iban": "CH10 0023 0000 0000 1234 5"
}| Champ | Type | Description |
|---|---|---|
iban | string | L'IBAN a valider. Les espaces et tirets sont supprimes automatiquement. Insensible a la casse. |
Reponse
Succes (200)
{
"iban": "CH1000230000000012345",
"valid": true,
"country": {
"code": "CH",
"name": "Switzerland"
},
"check_digits": "10",
"bban": {
"bank_code": "00230",
"account_number": "000000012345"
},
"bic": {
"code": "UBSWCHZH80A",
"bic8": "UBSWCHZH",
"bank_name": "UBS Switzerland AG",
"city": "Zürich",
"basis": "national_register",
"authoritative": true
},
"sepa": {
"member": true,
"schemes": ["SCT", "SDD"],
"vop_required": false,
"vop_participant": false
},
"issuer": {
"type": "bank",
"name": "UBS Switzerland AG",
"classification": "default"
},
"bank_code_check": {
"value": "00230",
"status": "verified",
"match": "register",
"register": "SIX BankMaster (Swiss IID / BC-Nummer register)",
"authoritative": true,
"institution": {
"name": "UBS Switzerland AG",
"street": "Bahnhofstrasse 45",
"post_code": "8098",
"town": "Zürich",
"country": "CH"
},
"as_of": "2026-08"
},
"risk_indicators": {
"issuer_type": "bank",
"country_risk": "standard",
"test_bic": false,
"sepa_reachable": true,
"sepa_reachable_scope": "country",
"vop_coverage": false
},
"clearing": {
"iid": "00230",
"name": "UBS Switzerland AG",
"type": "bank",
"town": "Zürich",
"sic": true,
"instant_payments_chf": true,
"eurosic": true,
"qr_iid": null
},
"formatted": "CH10 0023 0000 0000 1234 5",
"cost_usdc": 0.005,
"processing_ms": 1.23
}Champs de la reponse
Champs de premier niveau :
| Champ | Type | Present | Description |
|---|---|---|---|
iban | string | Toujours | IBAN nettoye (majuscules, sans espaces) |
valid | boolean | Toujours | Indique si l'IBAN a passe toutes les verifications |
country | object | IBAN valides | Code et nom du pays |
check_digits | string | IBAN valides | Les deux chiffres de controle |
bban | object | IBAN valides | Composants BBAN analyses |
bic | object | null | IBAN valides | Code BIC/SWIFT et donnees de l'etablissement (null si aucune correspondance trouvee) |
sepa | object | IBAN valides | Adhesion SEPA, schemas et exigence VoP |
issuer | object | IBAN valides avec BIC | Classification de l'etablissement |
bank_code_check | object | IBAN valides | Le code banque se résout-il dans les données de référence — et ce que cette réponse vaut (voir la section « verified » ci-dessous) |
next_steps | array | Selon le cas | Suites recommandées, lisibles par machine (screening conformité, vérification du bénéficiaire…), chacune avec sa raison |
risk_indicators | object | IBAN valides | Signal de risque composite pour la conformite |
clearing | object | null | IBAN CH/LI valides | Donnees de clearing suisses du SIX BankMaster (BC-Nummer, participation aux rails, QR-IID) ; null si l'IID n'y figure pas |
formatted | string | IBAN valides | IBAN formate avec des espaces tous les 4 caracteres |
error | string | IBAN invalides | Code d'erreur |
error_detail | string | IBAN invalides | Description de l'erreur lisible par un humain |
cost_usdc | number | Toujours | Cout de cette requete en USDC |
processing_ms | number | Toujours | Temps de traitement en millisecondes |
Objet country :
| Champ | Type | Description |
|---|---|---|
code | string | Code pays ISO 3166-1 alpha-2 |
name | string | Nom complet du pays en anglais |
Objet bban :
| Champ | Type | Description |
|---|---|---|
bank_code | string | Identifiant de la banque/l'etablissement extrait du BBAN |
branch_code | string? | Code de l'agence (present pour les pays comme FR, GB, ES, IT) |
account_number | string | Numero de compte extrait du BBAN |
Objet bic (present lorsqu'un BIC correspondant est trouve) :
| Champ | Type | Description |
|---|---|---|
code | string | Code BIC/SWIFT tel que la source le publie, 8 ou 11 caracteres ; comparer sur bic8 |
bic8 | string | Les huit caracteres de l'etablissement, et le champ sur lequel comparer un BIC fourni. Le code de branche (les trois derniers caracteres de code) est informatif : dans les reseaux cooperatifs il nomme la banque locale et les huit premiers sa centrale de compensation |
redirected_from | string? | Le code de banque demande, quand le registre a repondu pour celui qui a repris sa compensation (CH et LI : SIX redirige un IID concatene). L'IBAN reste valide : une redirection n'est pas un retrait |
bank_name | string | null | Nom de l'etablissement financier |
city | string | null | Ville de l'etablissement |
basis | string | D'où vient l'appariement code banque → BIC. national_register — le registre national du pays publie ce BIC pour ce code banque (aujourd'hui DE, AT, BE et BG) ; curated_map — notre carte de codes banque maintenue, une clé exacte et non un acte d'attribution ; directory_prefix — le repli par préfixe de BIC, qui peut correspondre à plusieurs établissements (voir bank_code_check.candidates) |
authoritative | boolean | Ce BIC peut-il être stocké et servir à régler. Dérivé de basis, true uniquement pour national_register. Voir la section « Régler contre ce BIC, ou le traiter comme indicatif ? » ci-dessous |
Objet sepa :
| Champ | Type | Description |
|---|---|---|
member | boolean | Indique si ce pays fait partie de la zone SEPA |
schemes | string[] | Schemas SEPA disponibles : SCT (virement), SDD (prelevement), SCT_INST (instantane) |
vop_required | boolean | Indique si la Verification du Beneficiaire (VoP) est obligatoire (reglement UE, depuis oct. 2025 pour la zone euro) |
vop_participant | boolean | null | Préparation VoP au niveau banque : true quand l'établissement résolu est listé comme prêt au registre du scheme VoP de l'EPC ; null quand aucun établissement n'est résolu |
Objet issuer (present lorsque le BIC est resolu) :
| Champ | Type | Description |
|---|---|---|
type | string | null | bank (traditionnelle), digital_bank (néobanque), emi (Établissement de Monnaie Électronique), payment_institution — ou null quand aucun établissement ne peut être étayé (par exemple, le code banque n'est pas un émetteur d'IBAN répertorié) |
name | string | Nom de l'établissement — le détenteur du BIC correspondant. Peut être renseigné même quand type est null : nommer le détenteur du BIC est un fait, en faire la banque de votre contrepartie serait une supposition |
classification | string | curated — le type est une identification positive issue de listes maintenues (EMI/néobanques/établissements de paiement) ; default — le type retombe sur bank parce que la plupart des détenteurs de BIC sont des banques. Comptez sur curated ; traitez default comme une présomption |
iban_issuer | string? | Uniquement pour les pays qui publient une liste des prestataires émetteurs d'IBAN (aujourd'hui : NL). confirmed — le code figure sur cette liste ; not_listed — non, type passe à null, et next_steps signale que le compte peut ne pas exister |
Detection vIBAN : Si
issuer.typeestemi,digital_bankoupayment_institution, l'IBAN est plus susceptible d'etre un IBAN virtuel (vIBAN). Ceci est utile pour la conformite AML/CFT dans le cadre du reglement AMLR de l'UE (juillet 2027).
Objet bank_code_check :
| Champ | Type | Description |
|---|---|---|
value | string | Le code banque extrait du BBAN, renvoyé pour vos journaux |
status | string | verified — le code se résout vers un établissement que nous savons nommer ; not_in_register — il ne se résout pas, dans les données de référence que nous détenons pour ce pays ; unavailable — aucun avis, soit parce que nous n'avons pas de données pour ce pays, soit parce que nous n'avons pas pu répondre à cet instant (voir reason) |
reason | string? | Pourquoi le verdict n'est pas verified. Présent sur chaque not_in_register et chaque unavailable, absent sur verified. not_allocated — un registre national nie le code, et c'est la seule valeur qui autorise un « ne pas envoyer » ; absent_from_reference_data — notre carte composite ne le porte pas, ce qui ne dit rien du registre national du pays ; no_reference_data_for_country ; register_names_no_holder — le registre définit cet espace de codes et ne publie aucun détenteur, c'est un silence et non une négation ; national_register_unavailable — le registre contre lequel ce pays se tranche d'ordinaire n'a pas pu être consulté, le verdict à côté n'a donc que le poids du composite ; lookup_failed — la consultation n'a pas pu s'exécuter du tout. Les deux dernières valeurs parlent de nous, jamais de votre bénéficiaire |
match | string | null | register — clé exacte dans le jeu de référence (déterministe) ; prefix — repli par préfixe de BIC, possible seulement où les codes banque sont alphabétiques ; voir candidates |
register | string | null | Nom du jeu de référence consulté |
authoritative | boolean | true uniquement là où le jeu de référence EST le registre national — voir ci-dessous |
candidates | number? | Sur match: "prefix" : nombre d'établissements correspondants. Au-delà de 1, la réponse n'est qu'indicative |
institution | object? | Ce que le registre national publie sur l'établissement titulaire : nom, adresse du siège, LEI quand il existe. Seulement sur les réponses autoritaires. La profondeur varie : CH/LI et AT adresse complète, DE code postal + ville (son registre n'a pas de rue), BE nom seul, BG nom seul — en cyrillique, tel que le registre le publie —, SK nom seul, avec les diacritiques slovaques tels que publiés. Les champs absents sont null, jamais devinés. C'est l'établissement titulaire du code banque, pas une agence, et pas la preuve d'un compte |
as_of | string | Mois des données de référence |
Objet risk_indicators :
| Champ | Type | Description |
|---|---|---|
issuer_type | string | null | Identique a issuer.type ; null quand aucun établissement n'a été étayé |
country_risk | string | standard, elevated (liste grise FATF) ou high (liste noire FATF / haut risque UE) |
test_bic | boolean | Indique si le BIC est un code de test/sandbox |
sepa_reachable | boolean | Indique si le pays du compte est dans la zone SEPA |
sepa_reachable_scope | string | country — l'affirmation d'accessibilité porte sur les schémas du pays, jamais sur ce compte précis |
vop_coverage | boolean | Indique si la VoP est obligatoire pour ce pays |
Ce que « verified » veut dire — et ce qu'il ne dit pas
bank_code_check.status: "verified" signifie que le code banque se résout vers un établissement que nous savons nommer dans les données de référence consultées. Ce que cela vaut est exactement ce que dit authoritative :
authoritative: true— le jeu de référence est le registre national lui-même. Aujourd'hui : CH et LI (SIX BankMaster), DE (Bankleitzahlendatei de la Bundesbank), FI (codes Finance Finland — attribués à des groupes bancaires, un résultat confirme le groupe), AT (répertoire OeNB), BE (liste de codes de la Banque nationale de Belgique), BG (registre BAE de la Banque nationale bulgare — le verdict porte sur le code banque à quatre lettres, positions 5-8 de l'IBAN ; les chiffres d'agence ne sont pas vérifiés séparément), SK (le prevodník des codes d'identification du système de paiement domestique de la Národná banka Slovenska). Dans ces pays,not_in_registersignifie que le code n'est pas attribué — une raison forte d'arrêter un paiement. Saint-Marin n'y figure délibérément pas : la liste des banques opérationnelles de la Banque centrale nomme le titulaire d'un code qu'elle porte, donc un résultat estverifiedavec un blocinstitution, mais elle ne publie pas l'attribution de l'espace ABI, donc une absence resteabsent_from_reference_dataetauthoritativerestefalse. Voir codes banque saint-marinais.authoritative: false— le jeu de référence est notre carte composite de codes banque, assemblée depuis des annuaires de BIC. Un résultat nomme le détenteur du BIC correspondant ; il ne prouve pas que cet établissement émet des IBAN. Là où les codes banque sont alphabétiques,match: "prefix"aveccandidates > 1signifie que la réponse n'est qu'indicative.
Une défaillance de notre côté est signalée par unavailable, jamais par un verdict. Lorsque les données de référence ne peuvent pas être lues — base illisible, table absente après un déploiement raté, requête qui expire — la réponse est status: "unavailable" avec reason: "lookup_failed" et register: null. Ce n'est jamais not_in_register : ce verdict signifie « aucun établissement ne détient ce code », et une panne chez nous n'est pas une preuve sur votre bénéficiaire. C'est reason qui sépare les deux situations en un seul jeton : lookup_failed et national_register_unavailable sont à nous de réparer, tout le reste est une affirmation sur le code. Tous se traitent pareil : continuez, et laissez un contrôle du nom du bénéficiaire trancher.
Rien de tout cela ne confirme que le compte existe, est ouvert, ou appartient à une personne donnée. Un IBAN structurellement valide nommant un établissement réel peut être fabriqué. Pour vérifier le bénéficiaire, utilisez la Verification of Payee des banques (sepa.vop_required indique quand elle est exigée) ou un contrôle du nom auprès de votre contrepartie — chaque fois qu'une réponse laisse ce vide ouvert, next_steps le dit explicitement.
Régler contre ce BIC, ou le traiter comme indicatif ?
Le BIC de la réponse est dérivé du code banque que porte l'IBAN, et ce que vaut cette dérivation dépend entièrement de ce qui l'a produite. bic.basis dit laquelle, et bic.authoritative en tire le seul booléen sur lequel un moteur de paiement peut brancher :
basis: "national_register",authoritative: true— le registre national du pays publie ce BIC pour ce code banque. Aujourd'hui, ce sont la Suisse, le Liechtenstein, l'Allemagne, l'Autriche, la Belgique, la Bulgarie, la Slovaquie et Saint-Marin : le BankMaster de SIX porte le BIC exact à 11 caractères par IID (numéro de clearing) pour CH et LI, la Bankleitzahlendatei de la Bundesbank porte le BIC exact à 11 caractères par BLZ, et les registres de l'OeNB, de la Banque nationale de Belgique, le registre BAE de la Banque nationale bulgare, le prevodník de la Národná banka Slovenska et la liste de la Banque centrale de Saint-Marin publient le BIC de l'établissement par code banque. Saint-Marin est le seul endroit où ce drapeau vauttruealors quebank_code_check.authoritativevautfalse: la liste de la Banque centrale associe un BIC à un code qu'elle porte, mais ne publie pas l'attribution de l'espace des codes. C'est le registre allemand qui fait qu'une Sparkasse se résout vers son propre BIC et non vers le BIC8 de la Landesbank partagée, et le registre suisse qui fait que l'IID 30020 se résout vers Crédit Mutuel de la Vallée SA (RBABCH22180) et non vers Entris Banking AG (RBABCH22) — le champ nomme cet appariement, il ne le crée pas. Comparez un BIC fourni surbic8: le code de branche est informatif, et dans un réseau coopératif il nomme la banque locale quand les huit premiers caractères nomment sa centrale de compensation. Stockable, et utilisable pour régler — à une exception près : un code que le registre lui-même marque retiré garde la basenational_registermaisauthoritativeretombe àfalse; lisezbank_code_check.retiredetsuperseded_by.basis: "curated_map",authoritative: false— c'est notre propre carte de codes banque qui a fait l'appariement, sur une clé exacte. Juste la plupart du temps, et ce n'est pas un acte d'attribution : aucune autorité ne le garantit.basis: "directory_prefix",authoritative: false— le repli par préfixe de BIC. Il peut correspondre à plusieurs établissements à la fois ;bank_code_check.candidatesdit combien, etnext_stepslèvebic_is_advisorydès qu'ils sont plus d'un.
Hors d'une base national_register, traitez le BIC comme indicatif : bon pour l'affichage, l'enrichissement et une indication de routage, à confirmer auprès du bénéficiaire ou de votre banque avant d'en faire une instruction de règlement stockée.
bic.authoritativeetbank_code_check.authoritativerépondent à deux questions différentes. La Suisse était l'endroit où l'écart se voyait, elle ne l'est plus : le BIC vient désormais de la colonne du SIX BankMaster lui-même, donc les deux valenttrue. Saint-Marin est l'endroit où ils divergent encore, en sens inverse : l'appariement est celui du superviseur (bic.authoritative: true) alors que l'espace des codes n'est pas le sien à attribuer (bank_code_check.authoritative: false). Le premier porte sur l'existence du code, le second sur l'appariement qui a produit le BIC.
IBAN invalide (200)
Lorsque l'IBAN est invalide, la reponse renvoie toujours un code 200 mais avec valid: false :
{
"iban": "CH5604835012345678000",
"valid": false,
"error": "checksum_failed",
"error_detail": "Modulo 97 check returned 42, expected 1.",
"cost_usdc": 0.005
}Codes d'erreur
| Code | Description |
|---|---|
invalid_format | L'IBAN contient des caracteres invalides ou est trop court |
unsupported_country | Le code pays n'est pas reconnu |
wrong_length | La longueur de l'IBAN ne correspond pas a la longueur attendue pour ce pays |
checksum_failed | La verification du checksum MOD-97 a echoue |
Exemples de code
cURL
curl -X POST https://api.ibanforge.com/v1/iban/validate \
-H "Content-Type: application/json" \
-d '{"iban": "DE89 3704 0044 0532 0130 00"}'Python
import requests
response = requests.post(
"https://api.ibanforge.com/v1/iban/validate",
json={"iban": "DE89370400440532013000"},
)
data = response.json()
if data["valid"]:
print(f"Bank: {data['bic']['bank_name']}")
print(f"Country: {data['country']['name']}")
print(f"SEPA: {data['sepa']['member']}")
print(f"Issuer type: {data['issuer']['type']}")
print(f"Risk: {data['risk_indicators']['country_risk']}")
else:
print(f"Invalid: {data['error_detail']}")TypeScript
const response = await fetch(
"https://api.ibanforge.com/v1/iban/validate",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ iban: "DE89370400440532013000" }),
}
);
const data = await response.json();
if (data.valid) {
console.log(`Bank: ${data.bic.bank_name}`);
console.log(`SEPA: ${data.sepa.member}, VoP: ${data.sepa.vop_required}`);
console.log(`Issuer: ${data.issuer.type} — ${data.issuer.name}`);
console.log(`Country risk: ${data.risk_indicators.country_risk}`);
} else {
console.log(`Invalid: ${data.error_detail}`);
}Passez à votre cas concret
Choisissez une première étape pour votre logiciel ou votre fichier fournisseurs.
Intégrer les contrôles IBAN à votre logiciel
Essayez une validation, examinez la réponse, puis reliez votre application à l’API ou à une intégration existante.
Découvrir le parcours APIContrôler un fichier fournisseurs
Déposez un CSV ou un fichier Excel et consultez gratuitement l’aperçu des constats. Achetez le classeur annoté si vous avez besoin du rapport complet. Sans compte ni abonnement.
Découvrir l’audit de fichiersLes informations bancaires disponibles varient selon le pays et la source. Ces contrôles ne confirment pas le titulaire du compte et ne garantissent pas la réussite d’un paiement.