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.

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": "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 :

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 (8 caracteres)
bank_namestring | nullNom de l'etablissement financier
citystring | nullVille de l'etablissement

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 — nous n'avons pas de données de référence pour ce pays, aucun avis
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. 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 BNB). Dans ces pays, not_in_register signifie 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" avec candidates > 1 signifie 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

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}`);
}