Enrich
POST /v1/enrich checks IBANs, BICs, LEIs, US routing numbers, German bank sort codes, currency codes and ISO 20022 external codes, and returns validity, normalized forms and derived facts.
What it checks
POST /v1/enrich validates financial identifiers against free, redistributable registry data. Send one item, or an array of up to 100:
type | Identifier | Checks |
|---|---|---|
iban | International Bank Account Number | Check digits (ISO 7064 mod 97), known country, exact length for that country, country-specific account structure |
bic | Bank Identifier Code (ISO 9362) | Structure, known country code, test-BIC convention |
currency | ISO 4217 currency code | Code exists, whether it is withdrawn |
purpose | ISO 20022 external purpose code | Membership of the published list |
btc | ISO 20022 bank transaction code | The DOMN/FMLY/SFML path (or DOMN/FMLY) exists |
lei | Legal Entity Identifier (ISO 17442) | 18 letters or digits plus 2 check digits; the check digits (ISO 7064 mod 97-10) |
aba | US ABA routing number | 9 digits, the 3-7-1 weighted check digit, an assigned first-two-digit prefix |
blz | German bank sort code (Bankleitzahl) | 8 digits, starting with a Bundesbank clearing area 1 to 8 |
type must be one of these eight values; anything else is an invalid-input 400 that lists them. Each value may be at most 64 characters after trimming.
Check identifiers
The request body is application/json: a single item object, or an array of 1 to 100 items. The response has the same shape, a single result for a single item and an array in the same order for an array.
curl -sS -X POST https://api.transmute.403fin.io/v1/enrich \
-H "Authorization: Bearer $TRANSMUTE_KEY" \
-H "Content-Type: application/json" \
-d '[
{"type": "iban", "value": "DE89370400440532013000"},
{"type": "bic", "value": "AAAADEFF"},
{"type": "aba", "value": "110000001"}
]'
[
{ "type": "iban", "valid": true, "normalized": "DE89370400440532013000",
"facts": { "country": "DE", "checkDigits": "89", "bban": "370400440532013000",
"bankCode": "37040044", "length": 22 },
"findings": [] },
{ "type": "bic", "valid": true, "normalized": "AAAADEFFXXX",
"facts": { "bic8": "AAAADEFF", "bic11": "AAAADEFFXXX", "institutionCode": "AAAA",
"countryCode": "DE", "locationCode": "FF", "branchCode": "XXX" },
"findings": [ { "code": "enrich.directory_unavailable", "severity": "info",
"message": "no BIC directory configured; structure-only result" } ] },
{ "type": "aba", "valid": false, "normalized": "110000001",
"facts": { "checkDigitValid": false, "category": "federal-reserve", "district": 11 },
"findings": [ { "code": "enrich.aba_checksum", "severity": "error",
"message": "3-7-1 weighted check digit failed" } ] }
]
| Result field | Meaning |
|---|---|
type | The type you sent |
valid | true when no finding has severity error |
normalized | The canonical form: IBAN, BIC and LEI uppercased with spaces removed, BICs padded to 11 characters with XXX, codes uppercased, routing numbers and sort codes with spaces removed. Present whenever the value can be normalized, even when it is invalid |
facts | Facts derived from the value, by type (below). Values are strings, integers and booleans, never floats |
findings | Observations, each with a code, a severity (info, warning or error) and a message, sorted by code |
Finding codes come from a closed enrich.* set, for example enrich.iban_checksum, enrich.currency_deprecated, enrich.lei_checksum, enrich.aba_prefix or enrich.blz_format. The API reference lists them all.
Facts by type
type | Facts |
|---|---|
iban | country, checkDigits, bban, bankCode and branchCode where the country defines them, length |
bic | bic8, bic11, institutionCode, countryCode, locationCode, branchCode |
currency | minorUnits, name, deprecated, replacedBy where applicable |
purpose | name, the code's registered name (for example SalaryPayment for SALA) |
btc | domain, family, subFamily, and their names domainName, familyName, subFamilyName |
lei | lou (the issuing organization's prefix), entity, checkDigits, checkDigitsValid |
aba | checkDigitValid, category (government, federal-reserve, thrift, electronic or travelers-cheque), district (Federal Reserve district 1 to 12) |
blz | clearingArea |
LEIs, routing numbers and sort codes
LEI. Positions 1 to 4 name the organization that issued the LEI, positions 5 to 18 identify the entity, and positions 19 and 20 are check digits. A value with the wrong shape gets enrich.lei_format; a value whose check digits do not match gets enrich.lei_checksum. Older LEIs often carry letters in positions 5 and 6; that is not flagged.
ABA routing number. Nine digits whose 3-7-1 weighted sum is a multiple of 10, starting with an assigned prefix: 00 (US government), 01 to 12 (Federal Reserve district), 21 to 32 (thrift institutions), 61 to 72 (electronic) or 80 (traveler's cheques). Failures get enrich.aba_format, enrich.aba_checksum or enrich.aba_prefix.
German bank sort code (BLZ). Eight digits; the first is the Bundesbank clearing area. A BLZ has no check digit of its own. A value that is not eight digits, or starts with 0 or 9, gets enrich.blz_format.
Reference data on the hosted API
The hosted API checks every type against the data built into transmute:
- IBAN country rules, BIC country codes, ISO 4217 currencies, and the ISO 20022 purpose and bank transaction code lists. The purpose codes are generated from the external code sets that the ISO 20022 Registration Authority publishes free of charge each quarter.
- The structure and check-digit rules for LEIs, routing numbers and sort codes.
transmute can also load directory files at startup, which add facts such as the bank name behind a BIC, routing number or sort code, and the BICs mapped to an LEI. The hosted API does not load any of them today. In practice:
bicresults are structure-only and carry anenrich.directory_unavailable(info) finding, so you can tell "well-formed, existence not checked" from a directory-backed answer. Licensed BIC directory data is never bundled with transmute.lei,abaandblzresults are structure and check-digit only, with the facts listed above. There is nobicsfact on an LEI and noleifact on a BIC, and noenrich.aba_not_in_directoryorenrich.blz_not_in_directoryfindings.
Self-hosted deployments can load their own directory files: a licensed BIC directory export, the public GLEIF BIC-to-LEI relationship file, a US routing directory, and the Deutsche Bundesbank sort code file. Loading them is an operator setting on the server, not a request option.
Privacy
Enrich inputs are identifiers, not message bodies, but IBANs are personal data, so the same discipline applies: values are never logged or written to the database (with an Idempotency-Key, the response is kept in the replay cache for 24 hours), error details name item indexes rather than values, and the usage record holds counts and status only.
Access and billing
Requires the enrich scope, granted by default on new keys. Enrich is metered like a validation: one usage event per call, whether it carries 1 item or 100. The 100-item cap is there to prevent abuse, not to price the call. The usual billing rules and quota headers apply.