Recover a garbled IBAN from OCR before paying
An OCR pass over a scanned invoice produces a near-miss IBAN — one wrong digit, an unreadable character. One paid call recomputes the check digits and recovers the missing characters before an agent pays the wrong account.
An agent that ingests invoices reads IBANs through OCR, and OCR is lossy: a
scanned account number comes back with one transposed digit or a character the
scanner could not resolve. Paying that number as-is routes money to the wrong
account — or to no account at all. Before the disbursement, one paid call —
GET /iban/repair — recomputes the check digits and
reconstructs the unreadable characters, returning valid candidates ranked by
known bank. This article shows where it fits an invoice-to-pay pipeline and how
to read its result without trusting a guess.
The problem: OCR turns a valid IBAN into a near-miss
A structurally valid IBAN satisfies the country’s BBAN layout (ISO 13616) and
the mod-97 checksum (ISO 7064). OCR breaks exactly those guarantees: it flips a
5 to a 6, or hands back a character it could not read at all. The result
fails validation — but it fails near the truth, usually a single edit away
from the correct number. A pure validator can only tell the agent the IBAN is
invalid; it cannot recover the right one.
Recovering it needs the country’s BBAN structure plus the national bank registry to break ties between candidates — bulky, frequently-updated public data that fits a pay-per-call lookup rather than an LLM’s weights.
The call: recompute, enumerate, rank
GET /iban/repair takes a degraded iban and returns a RepairResult: whether
it could be repaired, whether the answer is ambiguous, and a candidates
list. It works two ways:
- Wrong check digits (positions 3–4) on an otherwise intact body are recomputed and re-validated — no marking needed.
- Unreadable characters must be marked with a
?. The service substitutes each?with the characters allowed at that position by the country’s BBAN structure and keeps only the combinations that parse (structure + checksum).
Crucially, it does not guess silently: apart from the check digits, it never
corrects a character you did not mark — no implicit O→0 or I→1. If OCR is
unsure about a character, mark it ?; if it is confident but wrong, only the
checksum path applies.
Each surviving candidate carries bank_known and a full resolution (the same
shape GET /iban/resolve returns), so you get
bank/BIC/reachability for each candidate without a second call. Candidates
are ranked known-bank first — the registry breaks ambiguity that a validator
alone cannot.
Reading the result honestly
A repaired IBAN is a structurally valid candidate, not a guarantee the account exists or is the one on the invoice:
| Result | What the agent should do |
|---|---|
repaired: true, not ambiguous | One valid candidate — still verify it before paying |
repaired: true, ambiguous | Several parse; known-bank-first ranking is a hint, not a verdict — escalate |
already_valid: true | Input parsed as-is; no repair was needed |
repaired: false | TOO_AMBIGUOUS or UNREPAIRABLE — no confident repair |
Two scope facts to keep straight:
- A too-ambiguous or unrepairable input is a 200 with
repaired: false, not an error. Per the x402 golden rule, the agent pays for the answer to its question, and “this cannot be repaired” is a successful answer. The4xxrange is reserved for requests the service genuinely cannot answer. - Repair reconstructs structure (a number that passes layout + checksum and, ideally, maps to a known bank). It does not confirm the account is live, reachable, or owned by the payee. That confirmation is the next step.
Where it sits in an invoice-to-pay pipeline
Repair is the first gate after extraction, feeding the rest of the loop:
- OCR the invoice; extract the candidate IBAN, marking unreadable
characters
?. - Repair —
GET /iban/repair— recompute/enumerate; pick the candidate when unambiguous, escalate whenambiguous. - Resolve / screen the chosen IBAN
(
GET /iban/resolve) to confirm bank, BIC and reachability — and screen it if the workflow requires. - Pay the confirmed beneficiary through your own rails.
Each paid call follows the same x402 pattern as every Invoket endpoint. The
Quickstart walks the whole discover → 402 → pay → replay
cycle with runnable snippets. Price and accepted rails are not pinned here — they
are served live by the catalog; see the
endpoint reference for the current figure.
Repairing a batch of invoices
A reconciliation run rarely has one IBAN. POST /iban/repair/batch
repairs up to 500 degraded IBANs under one x402 settlement instead of one
settlement per row — the cost is one settlement per call regardless of batch
size, which is what makes a whole invoice batch workable as a single pre-payment
pass.
What repair does not do
- It does not invent corrections you did not mark, beyond the check digits — no silent OCR substitution.
- It does not assert that a repaired candidate is the IBAN on the invoice,
or that the account exists. A confident-looking single candidate still needs
GET /iban/resolveto confirm bank/BIC/reachability, and screening/Verification of Payee where the workflow demands it.
Used for what it is — a structural recovery step that turns an OCR near-miss into
ranked, valid candidates — it lets an autonomous accounting agent fix the
fixable and escalate the ambiguous, before money leaves. For the full field
reference and error codes, see the
GET /iban/repair documentation; for how agents
discover and call Invoket endpoints, see For agents.