Understanding SEPA pain.001 format: a complete guide
The pain.001 file is the standard format for SEPA credit transfers. In this guide, we explain its XML structure, mandatory fields, versions, best practices, and common errors to avoid.
What is pain.001?
pain.001 (Payment Initiation) is the XML message standardized by the EPC (European Payments Council) to initiate SEPA credit transfers. It is used by companies, government agencies, and financial institutions to transmit payment orders to their bank in a structured, machine-readable format.
This format is based on the ISO 20022 standard and is part of the Customer Credit Transfer Initiation message family. It is accepted by all banks in the SEPA zone, covering 36 countries including all EU/EEA members plus Switzerland, Monaco, San Marino, and the UK.
Pain.001 has largely replaced older national payment formats (such as CFONB in France, DTA in Germany, and CLIEOP in the Netherlands). A single pain.001 file can contain thousands of individual payment transactions, making it the standard for batch payroll processing, supplier payments, and treasury operations. Its companion format, pain.008, handles the reverse flow — SEPA direct debits (SDD) for collecting money from debtors.
XML file structure
A pain.001 file is structured in three hierarchical levels: GroupHeader (GrpHdr) contains global file information, PaymentInformation (PmtInf) holds debtor details and payment method, and CreditTransferTransactionInformation (CdtTrfTxInf) describes each individual transfer. Here is a complete example with namespace declaration:
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>MSG-20260210-001</MsgId>
<CreDtTm>2026-02-10T10:00:00</CreDtTm>
<NbOfTxs>3</NbOfTxs>
<CtrlSum>4500.00</CtrlSum>
<InitgPty><Nm>ACME SA</Nm></InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>PMT-001</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<ReqdExctnDt><Dt>2026-02-12</Dt></ReqdExctnDt>
<Dbtr><Nm>ACME SA</Nm></Dbtr>
<DbtrAcct>
<Id><IBAN>BE68539007547034</IBAN></Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId><BIC>GEBABEBB</BIC></FinInstnId>
</DbtrAgt>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>INV-2026-001</EndToEndId>
</PmtId>
<Amt><InstdAmt Ccy="EUR">1500.00</InstdAmt></Amt>
<CdtrAgt>
<FinInstnId><BIC>ABNANL2A</BIC></FinInstnId>
</CdtrAgt>
<Cdtr><Nm>Supplier NV</Nm></Cdtr>
<CdtrAcct>
<Id><IBAN>NL91ABNA0417164300</IBAN></Id>
</CdtrAcct>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>The root element must include the correct XML namespace (xmlns) matching the version you are using. The GroupHeader appears exactly once and contains the message ID, creation timestamp, transaction count, and control sum. Each PmtInf block groups transactions sharing the same debtor account and execution date. Within each PmtInf, one or more CdtTrfTxInf elements describe the individual credit transfers.
Mandatory fields in a pain.001 file
Here are all the essential fields required in any valid pain.001 file. Missing or malformed fields will cause immediate rejection by your bank:
- MsgId — Unique message identifier (max 35 characters). Must be unique per submission — banks reject duplicate MsgIds. Use a combination of date and sequence number (e.g. MSG-20260210-001).
- CreDtTm — Creation date and time in ISO 8601 format (e.g. 2026-02-10T10:00:00). Must reflect the actual file generation time. Some banks reject files with timestamps more than 24h in the past.
- NbOfTxs — Total number of individual credit transfer transactions in the file. Must exactly match the count of CdtTrfTxInf elements across all PmtInf blocks.
- CtrlSum — Control sum: the total of all individual transfer amounts, rounded to 2 decimal places. Must equal the sum of all InstdAmt values. A mismatch of even €0.01 causes rejection.
- InitgPty / Nm — Initiating party name — the entity generating the file. Maximum 70 characters. Must match the name registered with your bank.
- PmtInfId — Payment information identifier — unique within the file. Identifies a group of transactions sharing the same debtor and execution date. Used for reconciliation.
- PmtMtd — Payment method: 'TRF' for credit transfer. This field tells the bank which type of SEPA instruction to execute.
- ReqdExctnDt — Requested execution date in YYYY-MM-DD format. Must be a future banking business day. Banks typically accept dates up to 30 days in the future.
- DbtrAcct / IBAN — Debtor's IBAN — the account to be debited. Must pass mod-97 checksum validation and match an account registered for SEPA with your bank.
- EndToEndId — End-to-end identifier for each transaction (max 35 characters). Travels through the entire payment chain and appears on the creditor's bank statement. Critical for reconciliation.
Common errors in pain.001 files
These errors are frequently encountered during validation. Understanding them helps you prevent rejections before submitting to your bank:
Incorrect CtrlSum
The control sum does not match the sum of individual amounts. Always calculate by summing amounts rounded to 2 decimal places individually — do not round the total sum afterward. Example: 10.505 + 20.505 should be summed as 10.51 + 20.51 = 31.02, not rounded from 31.01.
Invalid IBAN
A malformed IBAN or incorrect mod-97 checksum. Each country has a specific IBAN length (Belgian: 16, French: 27, German: 22, Dutch: 18). Validate all IBANs before file generation using the mod-97 algorithm.
Execution date in the past
The ReqdExctnDt (requested execution date) must be today or a future banking business day. Weekends and bank holidays are not valid execution dates. Check your country's bank holiday calendar.
Duplicate MsgId
Banks reject files with a MsgId they have already processed. Use a combination of timestamp and unique sequence number. Never reuse MsgIds, even across different banking relationships.
Wrong namespace version
The XML namespace must match the version your bank expects. Using pain.001.001.03 namespace with a pain.001.001.09 structure will cause schema validation failure. Confirm with your bank which version they support.
Special characters in text fields
SEPA allows only a limited character set in text fields: a-z, A-Z, 0-9, and a few special characters (/ - ? : ( ) . , ' + space). Characters like ä, ö, ü, é, ñ must be transliterated. The euro sign (€) is not allowed in text fields.
Pain.001 versions: which one should you use?
The pain.001 format has evolved through several versions since its introduction. Each version adds new fields and capabilities while maintaining backward compatibility. Your bank may support one or more versions — always check their implementation guide.
| Version | Namespace | Year | Key changes |
|---|---|---|---|
| pain.001.001.03 | urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 | 2009 | Original SEPA version, still widely supported. Basic credit transfer fields. |
| pain.001.001.09 | urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 | 2019 | Added structured remittance info, regulatory reporting, purpose codes. Current EPC recommendation. |
| pain.001.001.11 | urn:iso:std:iso:20022:tech:xsd:pain.001.001.11 | 2023 | Latest ISO version. Enhanced LEI support, additional address fields. Adoption varies by bank. |
ValidateFin supports all three major versions. For new implementations, pain.001.001.09 is recommended as it offers the best balance of features and bank compatibility. If your bank still requires .03, ValidateFin will validate against that schema. Always test with your bank before switching versions in production.
Best practices for generating pain.001 files
Follow these proven guidelines to minimize rejections and ensure smooth payment processing:
- Validate before sending — Always validate your pain.001 file against the XSD schema before uploading to your bank. ValidateFin catches 100% of structural errors and most business rule violations in seconds.
- Use unique identifiers consistently — MsgId, PmtInfId, and EndToEndId should follow a predictable naming convention (e.g. date-based prefixes). This dramatically simplifies reconciliation and troubleshooting.
- Group transactions wisely — Group payments by execution date and currency in the same PmtInf block. This reduces processing fees at some banks and makes reconciliation cleaner.
- Handle character encoding properly — Always generate files in UTF-8. Transliterate non-SEPA characters (é→e, ß→ss, ü→ue) before building the XML. Untransliterated characters cause silent rejections at some banks.
- Test with small batches first — When implementing a new pain.001 generator or switching versions, start with a file containing 2-3 test transactions. Verify the bank accepts and processes them correctly before sending production volumes.
For high-volume payment operations, consider implementing automated validation as part of your payment pipeline. Generate the XML, validate with ValidateFin (or integrate schema validation into your code), and only submit to the bank if validation passes. This prevents rejected files and the manual intervention they require.
Validate your pain.001 file
Our SEPA validation tool checks your file against the official EPC XSD schema and displays the detail of each transaction. It validates IBANs, BICs, amounts, control sums, and structural compliance. No files are sent to our servers — everything runs in your browser.
Validate my SEPA fileFrequently Asked Questions
What is a SEPA pain.001 file?
A SEPA pain.001 file is an XML document conforming to ISO 20022 that initiates credit transfer payments. It contains debtor information, creditor details, amounts, and payment references. Banks use this standardized format to process batch payments across the 36-country SEPA zone. A single file can contain thousands of individual transfers.
What are the mandatory fields in a pain.001 file?
The mandatory fields include MsgId (message identifier, max 35 chars), CreDtTm (creation timestamp), NbOfTxs (transaction count), CtrlSum (sum of all amounts), InitgPty (initiating party), PmtInfId (payment information ID), PmtMtd (payment method — TRF), ReqdExctnDt (execution date), Dbtr (debtor name), DbtrAcct (debtor IBAN), and for each transaction: CdtrAcct (creditor IBAN), InstdAmt (amount with currency), and EndToEndId (end-to-end reference).
How can I validate my SEPA pain.001 file online?
Use ValidateFin's free SEPA Validator tool to check your pain.001 file against the official EPC XSD schemas. Upload your XML file — all validation happens locally in your browser with no data transmitted to any server, ensuring full GDPR compliance. The tool validates structure, IBANs, BICs, amounts, and control sums.
What is the difference between pain.001 and pain.008?
Pain.001 (Customer Credit Transfer Initiation) is for outgoing bank transfers — you push money to creditors. Pain.008 (Customer Direct Debit Initiation) is for collecting money from debtors — you pull funds from their accounts using a signed mandate. Both are ISO 20022 XML formats processed by banks in the SEPA zone, but they have different mandatory fields and business rules.
Which pain.001 version should I use?
For new implementations, pain.001.001.09 is recommended as it is the current EPC recommendation and offers structured remittance information, purpose codes, and regulatory reporting fields. Pain.001.001.03 is still widely supported for legacy systems. Pain.001.001.11 is the latest ISO version but bank support varies. Always check with your bank which versions they accept.
What characters are allowed in SEPA pain.001 text fields?
SEPA payment files use a restricted character set defined by the EPC: a-z, A-Z, 0-9, and special characters / - ? : ( ) . , ' + and space. National characters with accents (é, ü, ñ, etc.) must be transliterated (e→e, u→u, n→n). The euro sign (€) and other currency symbols are not allowed in text fields — amounts use the InstdAmt element with Ccy attribute instead.
How does the CtrlSum (control sum) work in pain.001?
CtrlSum is a checksum that must equal the exact sum of all individual InstdAmt values across all transactions in the file, rounded to 2 decimal places. It serves as an integrity check — if even €0.01 difference exists between CtrlSum and the actual sum, the entire file is rejected. Calculate it by summing pre-rounded amounts, not by rounding the total afterward.
Can a pain.001 file contain transactions in multiple currencies?
Standard SEPA credit transfers (SCT) are EUR-only. However, the pain.001 format itself supports multiple currencies through the InstdAmt Ccy attribute. Some banks accept non-EUR transactions in pain.001 for international payments, but this depends on your bank's implementation. For pure SEPA payments within the SEPA zone, always use EUR.
How many transactions can a single pain.001 file contain?
The ISO 20022 standard does not define a maximum, but practical limits depend on your bank. Most banks accept files with up to 100,000 transactions. Very large files (>50,000 transactions) may take longer to process and some banks recommend splitting them. The file size limit is typically 20-50 MB depending on the bank's upload channel.
What happens if my bank rejects a pain.001 file?
When a bank rejects a pain.001 file, you receive a pain.002 (Payment Status Report) indicating the rejection reason. Common rejection codes include AC01 (incorrect account number), AM05 (duplicate payment), DT01 (invalid date), and FF01 (invalid file format). To prevent rejections, always validate your file with ValidateFin before submission — the tool catches structural errors, invalid IBANs, and control sum mismatches.