pain.001 structured-address, before and after.
On November 14, 2026, the SWIFT MX/CBPR+ structured-address mandate makes the freeform <AdrLine> form of <PstlAdr> rejectable on cross-border MX. This page shows the exact XML change, the five required fields, and a working POST /v1/iso20022/pain.001 call.
The XML change
One block. Five fields.
The change applies to every party with a <PstlAdr> — Dbtr, Cdtr, UltmtDbtr, UltmtCdtr, InitgPty. Note the town is ASCII-folded (Zürich → Zurich) for the SWIFT "x" Latin-only character set.
Before · freeform (post-mandate reject)
<!-- BEFORE — freeform <AdrLine> (rejected on/after 2026-11-14) -->
<Cdtr>
<Nm>ACME Supplies GmbH</Nm>
<PstlAdr>
<AdrLine>Bahnhofstrasse 45</AdrLine>
<AdrLine>8001 Zürich</AdrLine>
<Ctry>CH</Ctry>
</PstlAdr>
</Cdtr>After · structured (mandate-compliant)
<!-- AFTER — structured <PstlAdr> (mandate-compliant) -->
<Cdtr>
<Nm>ACME Supplies GmbH</Nm>
<PstlAdr>
<StrtNm>Bahnhofstrasse</StrtNm> <!-- street, no number -->
<BldgNb>45</BldgNb> <!-- house / building no -->
<PstCd>8001</PstCd> <!-- postal code -->
<TwnNm>Zurich</TwnNm> <!-- town (ASCII-folded) -->
<Ctry>CH</Ctry> <!-- ISO 3166-1 alpha-2 -->
</PstlAdr>
</Cdtr>The five mandate fields
Every one is required.
| XML tag | API field | Meaning |
|---|---|---|
| <StrtNm> | street_name | Street name, without the house number. |
| <BldgNb> | building_number | House / building number. |
| <PstCd> | post_code | Postal / ZIP code. |
| <TwnNm> | town_name | Town or city name. |
| <Ctry> | country | ISO 3166-1 alpha-2 country code (uppercased at emission). |
A missing country (or a non-ISO 3166-1 alpha-2 value) is rejected with INVALID_ADDRESS. The builder emits the fields in canonical ISO 20022 order: StrtNm, BldgNb, PstCd, TwnNm, Ctry.
Build it
POST /v1/iso20022/pain.001
Send structured addresses as JSON; the builder validates and emits the mandate-compliant XML. The Idempotency-Key deterministically derives the MsgId so the same logical request always yields the same id — bank-side dedup is safe.
curl -X POST https://api.iso-compliant.com/v1/iso20022/pain.001 \
-H "Authorization: Bearer $ISO_COMPLIANT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: inv-2026-001234" \
-d '{
"debtor": {
"name": "Willkommen Treasury AG",
"iban": "CH9300762011623852957",
"address": {
"street_name": "Paradeplatz",
"building_number": "8",
"post_code": "8001",
"town_name": "Zurich",
"country": "CH"
}
},
"creditor": {
"name": "ACME Supplies GmbH",
"iban": "DE89370400440532013000",
"address": {
"street_name": "Bahnhofstrasse",
"building_number": "45",
"post_code": "8001",
"town_name": "Zurich",
"country": "CH"
}
},
"amount": "1250.00",
"currency": "EUR",
"end_to_end_id": "INV-2026-001234"
}'What happens if you send freeform
On a post-mandate ruleset, the legacy address_line field is rejected at validation — before any XML is serialised — so you catch it in your own pipeline, not at the bank.
// If you send the legacy freeform field on a post-mandate ruleset:
{
"creditor": {
"address": { "address_line": "Bahnhofstrasse 45, 8001 Zurich", "country": "CH" }
}
}
// → 422 STRUCTURED_ADDRESS_REQUIRED
// "creditor address uses legacy freeform 'address_line' which is rejected
// by the SWIFT MX/CBPR+ structured-address mandate effective 2026-11-14"Emit a mandate-compliant pain.001 today
100 documents/month free, no card. Point your existing SDK at api.iso-compliant.com.