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.
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": "UBSWCHZH",
"bank_name": "UBS Switzerland AG",
"city": "Zürich"
},
"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 (8 caracteres) |
bank_name | string | null | Nom de l'etablissement financier |
city | string | null | Ville de l'etablissement |
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 — nous n'avons pas de données de référence pour ce pays, aucun avis |
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. 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 BNB). Dans ces pays,not_in_registersignifie que le code n'est pas attribué — une raison forte d'arrêter un paiement.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.
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.
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}`);
}