GET /iban/repair
Repairs a degraded IBAN in a single call: it recomputes the check digits when
the body (BBAN) is intact, and recovers unreadable characters marked with ?
by validated enumeration (country structure + mod-97 checksum). Built for the
agent accounting pipeline that ingests invoices — an OCR pass turns a scanned IBAN
into a near-miss (one wrong digit, an unreadable character), and this endpoint
recovers it. Candidates are ranked known-bank first: the local bank registry
breaks the ambiguity that pure validators cannot. Purely local lookup → response
in milliseconds.
x402 golden rule: the agent pays for the answer to its question. “This IBAN
cannot be repaired” is a successful answer → 200 with repaired: false. The
4xx range is reserved for requests the service cannot answer.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
iban | string | yes | Degraded IBAN to repair; spaces and dashes tolerated, any case |
The ? convention
Mark each unreadable character with a question mark ?. The service
substitutes every ? with the characters allowed at that position (constrained by
the country’s BBAN structure) and keeps only the combinations that parse
(structure + checksum):
DE89370400440532013?00
The service does not guess without ?: there is no implicit OCR correction
(no O↔0, I↔1). The only exception is the check digits (positions 3–4):
an input without ? whose only fault is a wrong checksum is repaired by
recomputing them, and ?? in those two positions triggers the same recompute.
200 response — UnifiedResponse
{
"data": { ... },
"provenance": {
"source": "national-bank-registries",
"fetched_at": "2026-06-21T09:30:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-20T00:00:00Z" }
}
}
provenance.source: stable identifier of the bank registry.freshness.as_of: date of the registry snapshot (meta.json).
Fields of data — RepairResult
| Field | Type | Description |
|---|---|---|
input | string | The input as received, normalized (upper-cased, separators removed, ? kept) |
repaired | bool | true when at least one valid candidate was found |
already_valid | bool | true when the input was already a valid IBAN (single candidate = itself) |
ambiguous | bool | true when more than one candidate survives (or the candidate cap is hit) |
candidates | array | Repaired candidates, ranked known-bank first (see below) |
issue | string | null | Diagnostic code when candidates is empty: TOO_AMBIGUOUS or UNREPAIRABLE |
Each entry of candidates carries:
| Field | Type | Description |
|---|---|---|
iban | string | The repaired IBAN, in electronic form |
bank_known | bool | Whether (country, bank_code) maps to a bank in the registry (drives the ranking) |
resolution | object | The full resolve verdict for this IBAN — bank, BIC, reachability |
Each resolution is exactly what GET /iban/resolve
returns for the repaired IBAN, so you get bank/BIC/reachability without a second
call. See the single-call reference for the full field
table.
Case 1 — wrong check digits, recomputed
Input has no ? and only its checksum is wrong: the check digits are recomputed
(ISO 7064, mod-97-10) and re-validated. A single candidate, the correct IBAN.
{
"input": "DE89370400440532013001",
"repaired": true,
"already_valid": false,
"ambiguous": false,
"candidates": [
{
"iban": "DE89370400440532013000",
"bank_known": true,
"resolution": {
"iban": "DE89370400440532013000",
"valid": true,
"country": "DE",
"bank_code": "37040044",
"branch_code": null,
"bank": { "name": "Commerzbank", "bic": "COBADEFFXXX" },
"reachable": true,
"coverage": "full",
"issue": null
}
}
],
"issue": null
}
Case 2 — unreadable character recovered, single candidate
One ? at a digit position; only one substitution parses. Unambiguous.
{
"input": "DE8937040044053201300?",
"repaired": true,
"already_valid": false,
"ambiguous": false,
"candidates": [
{ "iban": "DE89370400440532013000", "bank_known": true, "resolution": { "...": "..." } }
],
"issue": null
}
Case 3 — several candidates, ranked known-bank first
When more than one substitution parses, all survivors are returned, known bank
first, with ambiguous: true. Ties are ordered lexicographically for a
deterministic result.
{
"input": "DE??370400440532013000",
"repaired": true,
"already_valid": false,
"ambiguous": true,
"candidates": [
{ "iban": "DE89370400440532013000", "bank_known": true, "resolution": { "...": "..." } },
{ "iban": "DE12370400440532013000", "bank_known": false, "resolution": { "...": "..." } }
],
"issue": null
}
Case 4 — already valid (successful answer → 200)
The input parses as-is: already_valid: true, repaired: false, a single
candidate equal to the input.
{
"input": "DE89370400440532013000",
"repaired": false,
"already_valid": true,
"ambiguous": false,
"candidates": [
{ "iban": "DE89370400440532013000", "bank_known": true, "resolution": { "...": "..." } }
],
"issue": null
}
Case 5 — cannot repair (successful answer → 200)
Too many ? to enumerate, or no substitution parses: repaired: false,
candidates: [], and issue tells which. This is not an error.
{
"input": "DE????????440532013000",
"repaired": false,
"already_valid": false,
"ambiguous": false,
"candidates": [],
"issue": "TOO_AMBIGUOUS"
}
issue codes: TOO_AMBIGUOUS (more wildcards than the service will enumerate) and
UNREPAIRABLE (a structurally wrong BBAN with no ? to recover).
Honest limits
- No guessing without
?. Apart from the check digits, the service never corrects characters you did not mark — it will not turnOinto0. Mark every unreadable character with?. - A too-ambiguous or unrepairable IBAN is a 200, not an error
(
repaired: false). Treat it as “no confident repair”, not a failure. - For the full per-field bank/BIC/reachability detail of a repaired IBAN, use
GET /iban/resolve— each candidate already embeds itsresolution.
Errors
| Status | code | Case |
|---|---|---|
| 400 | MISSING_PARAMETER | iban parameter missing or empty |
| 500 | INTERNAL | Internal error (detail logged, not exposed) |
{ "error": "missing or empty required parameter: iban", "code": "MISSING_PARAMETER" }
See also
GET /iban/resolve— resolve an IBAN to its bank, BIC and reachability; full field reference for each candidate’sresolution.POST /iban/repair/batch— repair many degraded IBANs in one settlement.- For agents — discovery surfaces, the live
/catalogand how settlement works.