pain.001 — SEPA credit transfer
pain.001.001.09JSON payment payload in, XSD-valid credit-transfer initiation out. Structured debtor/creditor addresses enforced for the Nov 14, 2026 mandate. CH (?profile=ch.03) and CGI-MP variants supported.
The outbound side of the engine builds pain.001 (SEPA credit transfer), pain.008 (SEPA direct debit), and the Swiss QR-bill (SPC v0200). Deterministic, byte-identical XML — no LLM in the request path — with structured-address enforcement for the Nov 14, 2026 mandate, deterministic-MsgId idempotency, and XSD subset validation that hard-fails on a content-model violation.
Outbound builders
Every builder takes a structured payload and returns the finished document — same shape, same guarantees across all three. No envelope template hunting, no per-schema glue code.
pain.001.001.09JSON payment payload in, XSD-valid credit-transfer initiation out. Structured debtor/creditor addresses enforced for the Nov 14, 2026 mandate. CH (?profile=ch.03) and CGI-MP variants supported.
pain.008.001.02CORE and B2B direct debit with mandate metadata enforcement and FRST / RCUR / OOFF / FNAL sequence-type grouping. Same deterministic emission contract as pain.001.
SPC v0200The full 31-line SPC v0200 payload, capped at 997 bytes, with mod-97 IBAN, mod-10 QRR (Lührmann) and QR-IBAN range checks. Renders to PDF / SVG / PNG bytes or the raw payload string.
What the engine guarantees
No LLM in the request path. The same payload renders the same bytes every time — element order, namespace prefixes, and whitespace are fixed. Diff two emissions and the only delta is the data you changed. That is what makes the output auditable and CI-stable.
Every debtor and creditor party is linted for the five structured fields — <StrtNm>, <BldgNb>, <PstCd>, <TwnNm>, <Ctry> — required when the SWIFT MX/CBPR+ mandate enforces on Nov 14, 2026. A fully-unstructured <AdrLine> is rejected at build; a hybrid (town + country) survives the post-deadline cutover.
The MsgId is derived deterministically from the payload, so re-POSTing the same payment never produces a second wire. The same request is the same document — safe to retry on a timeout without a duplicate-payment risk.
Output is validated against the XSD subset content model before it leaves the engine. A content-model violation hard-fails the build with the offending XPath — you never receive a structurally-invalid file that the bank would silently reject downstream.
Request → response
A structured payload in, a structured-address-compliant pain.001.001.09 back. The MsgId is deterministic, so the same request is idempotent — retry-safe on a timeout, with no duplicate wire.
Authorization: Bearer iso_live_9f3c…
Content-Type: application/json
{
"debtor": {
"name": "ACME Payroll AG",
"iban": "CH4431999123000889012",
"postal_address": {
"street_name": "Bahnhofstrasse",
"building_number": "12",
"post_code": "8001",
"town_name": "Zurich",
"country": "CH"
}
},
"creditor": {
"name": "Anna Müller",
"iban": "CH5604835012345678009",
"postal_address": {
"street_name": "Rue du Marché",
"building_number": "7",
"post_code": "1204",
"town_name": "Geneve",
"country": "CH"
}
},
"amount": "4250.00",
"currency": "CHF",
"end_to_end_id": "INV-2026-06-001"
}<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>MID-20260603-9f2c1a0db48e</MsgId>
<CreDtTm>2026-06-03T08:15:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>4250.00</CtrlSum>
<InitgPty><Nm>ACME Payroll AG</Nm></InitgPty>
</GrpHdr>
<PmtInf>
<Cdtr>
<Nm>Anna Müller</Nm>
<PstlAdr>
<StrtNm>Rue du Marché</StrtNm>
<BldgNb>7</BldgNb>
<PstCd>1204</PstCd>
<TwnNm>Geneve</TwnNm>
<Ctry>CH</Ctry>
</PstlAdr>
</Cdtr>
<!-- … -->
</PmtInf>
</CstmrCdtTrfInitn>
</Document>The MsgId is derived deterministically from the payload — re-POST the identical body and you get the identical document, never a second payment. Full field-level reference, the same call in curl / TypeScript / Python, and the pain.008 + QR-bill shapes live on the REST API page.
Pricing
You pay for the file we generate, not a slice of the money that moves through it. A €2,000,000 pain.001 and a €20 pain.001 cost the same to build — because the work is the same. The engine never touches the rail, the settlement, or the money itself; you keep your existing corporate bank relationships (EBICS / SFTP / API) and use iso-compliant purely to produce the file.
The unit of value
Not the API call. The demonstrable probability that the file is accepted at the customer's bank on the first attempt — backed by the XSD subset content model and the structured-address linter that run before the document ever leaves the engine.
Ship the mandate, this quarter
Point your existing SDK at api.iso-compliant.com and emit a mandate-compliant pain.001, pain.008, or QR-bill today. Sandbox iso_test_ keys for CI, live iso_live_ keys for production.