Validate an IBAN before an agent pays: bank, BIC and SEPA reach

IBAN validation with no account: check digits, the bank and BIC behind the account, and whether it is reachable for the SEPA scheme you intend to use. One paid call, answered offline.

By Matthias Begot · · Updated

An autonomous agent about to send money needs three facts about the destination IBAN before it commits: is the number structurally valid, which bank and BIC does it belong to, and is that account reachable over SEPA for the scheme it intends to use (SCT, SCT Inst, SDD Core or B2B). Those three answers come from one paid call — GET /iban/resolve — and this article shows where it sits in the x402 loop and how to read its result without overclaiming.

The problem: a valid IBAN is not a reachable account

An IBAN passing its mod-97 checksum (ISO 7064) tells you the number is well-formed for its country (ISO 13616). It does not tell you that a bank sits behind it, nor that the bank can actually receive the transfer your agent is about to send. An agent that pays purely on checksum validity can route a SEPA Instant transfer to a bank that does not participate in SCT Inst — the payment fails downstream, after the agent has already decided to send it.

Resolving the account before the disbursement turns that late failure into an early branch. The data needed to do it — national bank registries plus the EPC register of SEPA participants — is bulky, frequently updated public data that an LLM cannot reliably hold in its weights. It is a good fit for a pay-per-call lookup against a fresh snapshot.

The call: validity, bank, and SEPA reachability in one answer

GET /iban/resolve takes an iban and returns, in a single UnifiedResponse:

FieldWhat the agent learns
validStructural validity (country format + mod-97 checksum)
bankIssuing bank name and BIC, when the registry covers the country
reachableWhether a bank exists for the code; null when unknowable
coverage"full" or "structure_only" — how far the lookup could go
sepa_reachabilityPer-scheme reachability (SCT, SCT Inst, SDD Core/B2B)

The sepa_reachability block is the one a payout agent keys on. It reports, per scheme, whether the account’s bank is reachable:

"sepa_reachability": {
  "sct": true,
  "sct_inst": true,
  "sdd_core": true,
  "sdd_b2b": false,
  "schemes": ["SCT", "SCT_INST", "SDD_CORE"],
  "match": "exact"
}

If your agent intends a SEPA Instant transfer, it reads sct_inst before sending. A false there is a reason to fall back to standard SCT or to flag the payout — caught before the money moves, not after the rail rejects it.

match says where the reading came from: "exact" when the bank’s BIC is listed in the EPC register, "institution" when it is not and the schemes were inferred from that institution’s other BICs in the same country — an inference the endpoint names rather than hides. See the sepa_reachability reference for what that fallback will and will not assert.

Reading the result honestly

The endpoint is deliberate about what it will and will not assert:

  • reachable and sepa_reachability are null when they are unknowable (country outside the registry, or BIC absent from the EPC register with no unanimous institution to fall back on) — never a false false. Treat null as “no claim,” not as “unreachable.”
  • SEPA reachability is reported at the PSP level from the EPC register’s reference BICs. It is a decision-support signal, not a routing guarantee for one specific account.
  • Per the x402 golden rule, the agent pays for the answer to its question. “This IBAN is invalid” is a successful answer → 200 with valid: false, carrying an issue code (BAD_CHECKSUM, INVALID_BBAN, …). The 4xx range is reserved for requests the service genuinely cannot answer.

Where it sits in the x402 loop

Resolution is the lookup step before disbursement. The agent’s loop:

  1. Discover the endpoint and call it; receive the 402.
  2. Pay — sign the chosen rail and replay the request.
  3. Resolve — read valid, bank/bic, and sepa_reachability.
  4. Branch — stop on valid: false, pick the rail the account is reachable for, and only then pay the actual 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 in this article — they are served live by the catalog; see the endpoint reference for the current figure.

Resolving a list, not just one account

When the input is a list — a payout run, a vendor file, a reconciliation batch — POST /iban/resolve/batch resolves up to 500 IBANs under one x402 settlement instead of one settlement per row. The cost is one settlement per call, independent of how many IBANs the batch carries, which is the difference between a workable pre-payment check and a per-item toll.

What resolve does not do

Be precise about scope, because “verify a bank account” is easy to overread:

  • It resolves the account to a bank, BIC, and SEPA reachability — it does not screen that bank against sanctions lists or assess jurisdiction risk. That is a separate endpoint, covered in Sanctions-screen a beneficiary IBAN before an agent pays it (GET /iban/screen).
  • It does not check that the account holder’s name matches who you intend to pay — name verification is out of scope for this endpoint.

Used for what it is — a fast lookup of validity, bank, and SEPA reachability — it lets an autonomous agent pick the right rail and skip the accounts it cannot reach, before the transfer leaves. For the full field reference and error codes, see the GET /iban/resolve documentation; for how agents discover and call Invoket endpoints, see For agents.