POST /iban/verify-name/batch
Runs Verification of Payee (VoP / Confirmation of Payee) over a list of
name/IBAN pairs in a single call: up to 50 pairs, settled with one x402
payment for the whole batch. Each pair runs through the same engine as
GET /iban/verify-name — it checks that the name you
are about to pay matches the account holder behind the IBAN, returns one of five
match bands, and relays the corrected name on a near-miss.
One settlement for N pairs is built to pre-check a beneficiary list before a run
of SEPA transfers: clean and verify the payees in one shot, then release the
campaign. Unlike a flat IBAN batch, each pair is a real paid lookup at the VoP
provider, so the call is priced per pair with a single x402 settlement — a base
plus a per-pair unit (floor at N = 1), so cost scales with volume while settlement
happens once. See the live /catalog for the authoritative
price.
x402 golden rule: the agent pays for the answer to its question. A well-formed
batch is a successful answer → 200, even when some pairs come back unavailable
or not_supported (each is a valid verdict, exactly as in the single call). The 4xx
range is reserved for requests the service cannot answer (missing or malformed body,
empty list, batch over the cap). A total provider failure, where no pair could be
verified, returns a typed 5xx and is not settled.
Request
POST with a JSON body. Set Content-Type: application/json.
POST /iban/verify-name/batch
Content-Type: application/json
{
"pairs": [
{ "iban": "DE89370400440532013000", "name": "Erika Mustermann" },
{ "iban": "FR1420041010050500013M02606", "name": "ACME SARL" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
pairs | object[] | yes | Name/IBAN pairs to verify, 1 to 50 entries |
Each item has the same two inputs as the single call:
| Field | Type | Required | Description |
|---|---|---|---|
iban | string | yes | IBAN of the payee account; spaces and dashes tolerated |
name | string | yes | Name to verify against the account holder — person or company |
200 response — UnifiedResponse
{
"data": {
"count": 2,
"results": [ { ... }, { ... } ]
},
"provenance": {
"source": "epc-vop-scheme",
"fetched_at": "2026-06-22T09:30:00Z",
"freshness": { "kind": "live" }
}
}
count: number of verified pairs, equal toresults.lengthand to the number of pairs submitted.results: one verdict per pair, in the same order as the input. Each element has exactly the same shape as thedataofGET /iban/verify-name—iban_valid,name_match,bic,suggested_name,coverage. See the single-call reference for the five match bands and per-case examples.- A single
provenanceblock covers the whole batch.
Per-pair honesty — coverage
Like the single call, every result carries a coverage marker. In a batch,
coverage.reason adds two batch-specific codes that signal a pair the batch could
not complete — honestly, in the pair’s own verdict rather than as a silent gap:
reason | Meaning |
|---|---|
BUDGET_EXCEEDED | This pair was not verified within the batch’s time/lookup budget |
LOOKUP_FAILED | The VoP lookup for this pair failed at the provider (the rest of the batch answered) |
These pairs are returned with name_match: "unavailable" and remain part of a
partial 200: the batch is billed for the answers it produced. Only a total
failure — no pair verified at all — leaves the 200 range as a 5xx and is not
settled.
Example — mixed batch (match, no_match and partial entries → 200)
{
"data": {
"count": 3,
"results": [
{
"iban_valid": true,
"name_match": "match",
"bic": "COBADEFFXXX",
"suggested_name": null,
"coverage": { "supported": true, "country": "DE", "reason": null }
},
{
"iban_valid": true,
"name_match": "close_match",
"bic": "COBADEFFXXX",
"suggested_name": "Erika Mustermann",
"coverage": { "supported": true, "country": "DE", "reason": null }
},
{
"iban_valid": true,
"name_match": "unavailable",
"bic": null,
"suggested_name": null,
"coverage": { "supported": true, "country": "FR", "reason": "BUDGET_EXCEEDED" }
}
]
},
"provenance": {
"source": "epc-vop-scheme",
"fetched_at": "2026-06-22T09:30:00Z",
"freshness": { "kind": "live" }
}
}
The second pair is a near-miss carrying its corrected suggested_name, while the
third is a valid IBAN the batch could not verify within budget — signalled with
coverage.reason: "BUDGET_EXCEEDED" rather than dropped.
Errors
Only requests the service cannot answer leave the 200 range. The cap is checked before any lookup, so an oversized batch is rejected without being billed an answer. A total provider failure (no pair verified) is never turned into a 200.
| Status | code | Case |
|---|---|---|
| 400 | INVALID_BODY | Body missing or not JSON, not an object, or pairs missing |
| 400 | EMPTY_BATCH | pairs is an empty array ([]) |
| 400 | BATCH_TOO_LARGE | More than 50 pairs in a single call |
| 503 | PROVIDER_UNAVAILABLE | VoP provider not configured, or every lookup failed (total failure, not settled) |
| 500 | INTERNAL | Internal error (detail logged, not exposed) |
{ "error": "batch too large: 51 pairs, the maximum is 50", "code": "BATCH_TOO_LARGE" }
See also
GET /iban/verify-name— single-pair reference and full field documentation (match bands, PII posture,coverage).POST /iban/resolve/batch— resolve many IBANs to bank, BIC and SEPA reachability in one settlement.- For agents — discovery surfaces, the live
/catalogand how settlement works.