Aller au contenu
IBANforge

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-teteValeurRequis
Content-Typeapplication/jsonOui
AuthorizationBearer ifk_... (clé API gratuite)L'un des deux
X-PAYMENTToken de paiement x402L'un des deux

Corps

{
  "iban": "CH10 0023 0000 0000 1234 5"
}
ChampTypeDescription
ibanstringL'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 :

ChampTypePresentDescription
ibanstringToujoursIBAN nettoye (majuscules, sans espaces)
validbooleanToujoursIndique si l'IBAN a passe toutes les verifications
countryobjectIBAN validesCode et nom du pays
check_digitsstringIBAN validesLes deux chiffres de controle
bbanobjectIBAN validesComposants BBAN analyses
bicobject | nullIBAN validesCode BIC/SWIFT et donnees de l'etablissement (null si aucune correspondance trouvee)
sepaobjectIBAN validesAdhesion SEPA, schemas et exigence VoP
issuerobjectIBAN valides avec BICClassification de l'etablissement
bank_code_checkobjectIBAN validesLe 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_stepsarraySelon le casSuites recommandées, lisibles par machine (screening conformité, vérification du bénéficiaire…), chacune avec sa raison
risk_indicatorsobjectIBAN validesSignal de risque composite pour la conformite
clearingobject | nullIBAN CH/LI validesDonnees de clearing suisses du SIX BankMaster (BC-Nummer, participation aux rails, QR-IID) ; null si l'IID n'y figure pas
formattedstringIBAN validesIBAN formate avec des espaces tous les 4 caracteres
errorstringIBAN invalidesCode d'erreur
error_detailstringIBAN invalidesDescription de l'erreur lisible par un humain
cost_usdcnumberToujoursCout de cette requete en USDC
processing_msnumberToujoursTemps de traitement en millisecondes

Objet country :

ChampTypeDescription
codestringCode pays ISO 3166-1 alpha-2
namestringNom complet du pays en anglais

Objet bban :

ChampTypeDescription
bank_codestringIdentifiant de la banque/l'etablissement extrait du BBAN
branch_codestring?Code de l'agence (present pour les pays comme FR, GB, ES, IT)
account_numberstringNumero de compte extrait du BBAN

Objet bic (present lorsqu'un BIC correspondant est trouve) :

ChampTypeDescription
codestringCode BIC/SWIFT tel que la source le publie, 8 ou 11 caracteres ; comparer sur bic8
bic8stringLes 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_fromstring?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_namestring | nullNom de l'etablissement financier
citystring | nullVille de l'etablissement
basisstringD'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)
authoritativebooleanCe 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 :

ChampTypeDescription
memberbooleanIndique si ce pays fait partie de la zone SEPA
schemesstring[]Schemas SEPA disponibles : SCT (virement), SDD (prelevement), SCT_INST (instantane)
vop_requiredbooleanIndique si la Verification du Beneficiaire (VoP) est obligatoire (reglement UE, depuis oct. 2025 pour la zone euro)
vop_participantboolean | nullPré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) :

ChampTypeDescription
typestring | nullbank (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é)
namestringNom 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
classificationstringcurated — 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_issuerstring?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.type est emi, digital_bank ou payment_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 :

ChampTypeDescription
valuestringLe code banque extrait du BBAN, renvoyé pour vos journaux
statusstringverified — 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)
reasonstring?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
matchstring | nullregister — 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
registerstring | nullNom du jeu de référence consulté
authoritativebooleantrue uniquement là où le jeu de référence EST le registre national — voir ci-dessous
candidatesnumber?Sur match: "prefix" : nombre d'établissements correspondants. Au-delà de 1, la réponse n'est qu'indicative
institutionobject?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_ofstringMois des données de référence

Objet risk_indicators :

ChampTypeDescription
issuer_typestring | nullIdentique a issuer.type ; null quand aucun établissement n'a été étayé
country_riskstringstandard, elevated (liste grise FATF) ou high (liste noire FATF / haut risque UE)
test_bicbooleanIndique si le BIC est un code de test/sandbox
sepa_reachablebooleanIndique si le pays du compte est dans la zone SEPA
sepa_reachable_scopestringcountry — l'affirmation d'accessibilité porte sur les schémas du pays, jamais sur ce compte précis
vop_coveragebooleanIndique 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_register signifie 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 est verified avec un bloc institution, mais elle ne publie pas l'attribution de l'espace ABI, donc une absence reste absent_from_reference_data et authoritative reste false. 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" avec candidates > 1 signifie 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 vaut true alors que bank_code_check.authoritative vaut false : 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 sur bic8 : 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 base national_register mais authoritative retombe à false ; lisez bank_code_check.retired et superseded_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.candidates dit combien, et next_steps lève bic_is_advisory dè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.authoritative et bank_code_check.authoritative ré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 valent true. 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

CodeDescription
invalid_formatL'IBAN contient des caracteres invalides ou est trop court
unsupported_countryLe code pays n'est pas reconnu
wrong_lengthLa longueur de l'IBAN ne correspond pas a la longueur attendue pour ce pays
checksum_failedLa 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 API

Contrô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 fichiers

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