Reference🏦 Bank reconciliationAdvanced⏱ 17 min read

🧩 ISO 20022 for statements: the camt messages

camt.052, camt.053, camt.054: the XML structure, Bank Transaction Codes, the pain → camt link, and automated matching

camt.052, 053, 054: three messages, three uses

The camt family (Cash Management) carries account reporting in ISO 20022. Three messages cover most reconciliation needs, as direct replacements for the MT942, MT940, and MT900/910.

⏱️
camt.052 (intraday)
Bank to Customer Account Report: balances and entries during the day, with several runs possible. It replaces the MT942 and is used to track the cash position in real time.
📄
camt.053 (end-of-day statement)
Bank to Customer Statement: the official, complete statement for the accounting day, with guaranteed opening and closing balances. It replaces the MT940, and reconciliation relies on it.
🔔
camt.054 (advices and batch details)
Bank to Customer Debit Credit Notification: an individual debit or credit advice, plus the breakdown of batches booked as a single total on the statement. It replaces the MT900/910.
Criterioncamt.052camt.053camt.054
FrequencyIntraday (n runs per day)Once per business day per accountReal time or batched
Balances reportedInterim (ITBD)OPBD, CLBD, CLAV, FWAVNone (advice)
Evidential value for accountingIndicativeReference for reconciliationSupplementary detail
MT equivalentMT942MT940MT900/MT910
Typical useCash position, balancingReconciliation and bookingBatch details (direct debits collected, cards) and notifications
The three camt messages compared
ℹ️
Several versions of the message coexist, varying by bank and by product. The French banking community historically rolled out camt.053.001.02 (CFONB guidelines), while CBPR+ and newer offerings use .001.08 and later. The structures are similar but not identical (for example, Sts becomes a Cd/Prtry choice in .08), so the parser has to be tested by version AND by bank.

The structure of camt.053

The camt.053 is an XML document whose hierarchy strictly separates the message (GrpHdr), the statement for each account (Stmt), the booked entry (Ntry), and the underlying transaction (TxDtls). The Ntry/TxDtls distinction is the key to reading it, because one entry can aggregate a whole batch while each transaction stays individually accessible.

BkToCstmrStmt1 messageGrpHdrMsgId · CreDtTmStmt1 per account · ElctrncSeqNbAcct + Bal[ ]IBAN · OPBD CLBD CLAV ITBDNtryThe ENTRY as booked (BOOK)NtryDtls / BtchNbOfTxs = 350TxDtls #1TxDtls #21 → nTxDtls #350Refs/EndToEndIdRefs/MndtId (UMR)RmtInf/Strd (invoices)Chrgs (separate fees)AmtDtls (currency)CheckOPBD + Σ signed Ntry = CLBDWhat accounting seesRequired for matching1 Ntry = 1 lump-sum credit for the batch. An engine that stops at Ntry will never match an individual return.Some banks don't return TxDtls for batches: the detail then arrives in a separate camt.054.
ItemPathRole
GrpHdrBkToCstmrStmt/GrpHdrMessage header: unique MsgId, CreDtTm (creation timestamp)
StmtBkToCstmrStmt/StmtOne statement per account: Id, ElctrncSeqNb (sequence number, equivalent to :28C:), FrToDt
AcctStmt/AcctAccount: IBAN, currency, owner (Ownr)
BalStmt/Bal (repeating)Typed balances: OPBD opening, CLBD closing booked, CLAV available, ITBD interim, FWAV forward
NtryStmt/Ntry (repeating)Booked entry: amount, direction (CdtDbtInd), status (BOOK/PDNG), dates (BookgDt, ValDt), bank reference (AcctSvcrRef), BkTxCd
NtryDtlsNtry/NtryDtlsEntry details: number of transactions in the batch (Btch/NbOfTxs) and the list of TxDtls
TxDtlsNtryDtls/TxDtls (repeating)The individual transaction: references, detailed amounts, parties, remittance information
RefsTxDtls/RefsThe goldmine for matching: MsgId, PmtInfId, InstrId, EndToEndId, MndtId, TxId, all returned without truncation
RmtInfTxDtls/RmtInfRemittance information: Ustrd (free text, 140 characters) or Strd (structured: invoice references, ISO 11649 “RF” creditor reference)
Core elements of camt.053
🔑
Ntry ≠ TxDtls
A batch of 350 collected direct debits appears as 1 `Ntry` (the total credit) containing 350 `TxDtls`, or as 1 Ntry pointing to a detailed camt.054. A reconciliation engine that stops at the entry level has no data to match individual returns, because they appear only in the TxDtls.

Bank Transaction Codes: the Domain / Family / SubFamily taxonomy

The Bank Transaction Code (BTC) is an ISO-published code that classifies every entry on three levels: domain, family, and subfamily. The MT940 offered only a code such as NTRF, and the CFONB120 a two-digit AFB code. The BTC states what the transaction is, in the same terms from one bank to the next, as long as the bank populates it.

DomainFamilySubFamilyMeaning
PMNTRCDTESCTSEPA credit transfer received
PMNTICDTESCTSEPA credit transfer sent
PMNTRDDTESDDSEPA Core direct debit charged to the account
PMNTRDDTBBDDSEPA B2B direct debit charged
PMNTIDDTESDDSEPA direct debit batch collected (creditor), credited
PMNTCCRDPOSDCard payment at the point of sale (cardholder side)
PMNTCNTRCDPTCash deposit at the branch counter
PMNTICDTCHRGFees on an outgoing credit transfer
Common Bank Transaction Codes

The BTC sits alongside a proprietary code (Prtry). In France, banks use it to return the legacy AFB transaction code (with Issr = CFONB). This eases the migration of reconciliation engines built on CFONB120, because every entry carries both codes at once.

ℹ️
Build the accounting routing table on the BTC first, with the proprietary code as a fallback. An entry coded PMNT/RCDT/ESCT is then posted and matched automatically, whatever its description says.

A complete annotated camt.053

A camt.053.001.08 statement for July 10, 2026: an Adyen payout as a credit and a rent direct debit as a debit. The entries and balances deliberately mirror the CFONB120 example in the next topic, so you can compare the two formats on an identical case.

camt.053 statement for July 10, 2026 (annotated)
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.08">
  <BkToCstmrStmt>
    <GrpHdr>
      <MsgId>CAMT053-20260711-000132</MsgId>       <!-- unique message identifier -->
      <CreDtTm>2026-07-11T04:07:12+02:00</CreDtTm> <!-- generated by the bank at 04:07 -->
    </GrpHdr>
    <Stmt>
      <Id>STMT-2026-07-10-132</Id>
      <ElctrncSeqNb>132</ElctrncSeqNb>             <!-- sequence number = detects a missing statement -->
      <CreDtTm>2026-07-11T04:07:12+02:00</CreDtTm>
      <Acct>
        <Id><IBAN>FR7630004008120001234567887</IBAN></Id>
        <Ccy>EUR</Ccy>
        <Ownr><Nm>ACME DISTRIBUTION SAS</Nm></Ownr>
      </Acct>
      <Bal>                                        <!-- opening balance -->
        <Tp><CdOrPrtry><Cd>OPBD</Cd></CdOrPrtry></Tp>
        <Amt Ccy="EUR">152340.25</Amt>
        <CdtDbtInd>CRDT</CdtDbtInd>
        <Dt><Dt>2026-07-09</Dt></Dt>
      </Bal>
      <Bal>                                        <!-- closing booked balance -->
        <Tp><CdOrPrtry><Cd>CLBD</Cd></CdOrPrtry></Tp>
        <Amt Ccy="EUR">162999.75</Amt>             <!-- 152340.25 + 12500.00 - 1840.50 -->
        <CdtDbtInd>CRDT</CdtDbtInd>
        <Dt><Dt>2026-07-10</Dt></Dt>
      </Bal>
      <Ntry>                                       <!-- ENTRY 1: Adyen payout -->
        <Amt Ccy="EUR">12500.00</Amt>
        <CdtDbtInd>CRDT</CdtDbtInd>
        <Sts><Cd>BOOK</Cd></Sts>                   <!-- booked (vs. PDNG pending) -->
        <BookgDt><Dt>2026-07-10</Dt></BookgDt>
        <ValDt><Dt>2026-07-10</Dt></ValDt>
        <AcctSvcrRef>BNK7593012</AcctSvcrRef>      <!-- bank reference (= //ref in the MT940) -->
        <BkTxCd>
          <Domn>
            <Cd>PMNT</Cd>
            <Fmly><Cd>RCDT</Cd><SubFmlyCd>ESCT</SubFmlyCd></Fmly> <!-- SEPA credit transfer received -->
          </Domn>
          <Prtry><Cd>15</Cd><Issr>CFONB</Issr></Prtry>            <!-- AFB code alongside -->
        </BkTxCd>
        <NtryDtls>
          <TxDtls>
            <Refs>
              <!-- full EndToEndId, NOT truncated: the key to automated matching -->
              <EndToEndId>ADYEN-SETTLEMENT-2026-BATCH42</EndToEndId>
            </Refs>
            <RltdPties>
              <Dbtr><Pty><Nm>ADYEN N.V.</Nm></Pty></Dbtr>         <!-- payer -->
            </RltdPties>
            <RmtInf><Ustrd>SETTLEMENT BATCH 42 ACME FR</Ustrd></RmtInf>
          </TxDtls>
        </NtryDtls>
      </Ntry>
      <Ntry>                                       <!-- ENTRY 2: SEPA direct debit charged -->
        <Amt Ccy="EUR">1840.50</Amt>
        <CdtDbtInd>DBIT</CdtDbtInd>
        <Sts><Cd>BOOK</Cd></Sts>
        <BookgDt><Dt>2026-07-10</Dt></BookgDt>
        <ValDt><Dt>2026-07-10</Dt></ValDt>
        <AcctSvcrRef>BNK7593044</AcctSvcrRef>
        <BkTxCd>
          <Domn><Cd>PMNT</Cd><Fmly><Cd>RDDT</Cd><SubFmlyCd>ESDD</SubFmlyCd></Fmly></Domn>
        </BkTxCd>
        <NtryDtls>
          <TxDtls>
            <Refs>
              <EndToEndId>RENT-2026-07</EndToEndId>
              <MndtId>UMR-DOCKSIDE-0042</MndtId>  <!-- UMR of the direct debit mandate -->
            </Refs>
            <RltdPties><Cdtr><Pty><Nm>DOCKSIDE PROPERTIES</Nm></Pty></Cdtr></RltdPties>
            <RmtInf><Ustrd>WAREHOUSE RENT JULY 2026</Ustrd></RmtInf>
          </TxDtls>
        </NtryDtls>
      </Ntry>
    </Stmt>
  </BkToCstmrStmt>
</Document>
  • Integrity check: OPBD 152,340.25 + 12,500.00 − 1,840.50 = 162,999.75 = CLBD. ✔
  • The 29-character EndToEndId comes through intact, whereas the MT940’s :61: field would have truncated it to 16.
  • The MndtId (UMR) lets you match the debit against the mandate database without parsing descriptions.
  • Dual coding, BTC plus proprietary AFB code, allows a smooth migration from CFONB120.

pain.001, pain.008, and the link from batch to statement

The pain messages (Payment Initiation) are the outbound counterpart of camt: pain.001 carries credit transfer batches, pain.008 direct debit batches, and pain.002 returns statuses (accepted, rejected, reason). What ISO 20022 adds is end-to-end reference flow: the identifiers issued in the pain batch come back in the camt that reports its execution.

Message formatRoleKey references issuedHow camt reports it
pain.001Credit transfer batch (SCT / SCT Inst)PmtInfId (batch), EndToEndId and InstrId (per transfer)camt.054 (batch debit advice), camt.053 (Ntry + TxDtls/Refs)
pain.008SEPA direct debit batch (Core / B2B)PmtInfId, EndToEndId, MndtId (UMR)Batch credit, then individual debits for returns (RtrInf with reason code)
pain.002Processing status reportACCP/RJCT statuses + ISO reason codesUpstream of the statement: filters out technical rejects
pain messages and how they show up in statements
Closed loop from batch to statement
ERP / treasury
Sends the pain.001
PmtInfId PMT-2026-07-10-01, 120 transfers, one EndToEndId per invoice
Bank
Acknowledges with a pain.002
118 accepted, 2 rejected (invalid IBAN, closed account)
Bank
Executes and debits the account
One total debit for the batch, on the requested execution date
Bank
Notifies with a camt.054
Details of the 118 executed transfers, linked to the PmtInfId
Bank
Sends the camt.053 on D+1
Batch Ntry + TxDtls carrying each EndToEndId
Reconciliation engine
Matches automatically
Statement EndToEndId = batch EndToEndId = ERP invoice: cash application with no manual work
🔑
The EndToEndId must be meaningful and unique (for example, INV-2026-18452). Never set it to NOTPROVIDED, which leaves the chain with no usable key. It travels all the way to the counterparty’s bank and comes back on both parties’ statements, so two back offices can reconcile on the same key.

Benefits, limitations, and adoption strategy

  • Untruncated references: 35-character EndToEndId, PmtInfId, MndtId. Deterministic matching becomes the norm.
  • Structured remittance data: RmtInf/Strd can carry invoice numbers and the ISO 11649 creditor reference (“RF”). Customer cash application can be automated.
  • Standardized semantics: Bank Transaction Codes replace guesswork on descriptions.
  • Multicurrency and complete parties: original amounts (AmtDtls), exchange rates, ultimate debtor (UltmtDbtr).
  • One standard from batch to statement: pain → pacs → camt, with the same identifiers throughout.
⚠️
Real-world limitations
Not every bank populates camt messages with the same care. Common defects include missing TxDtls on some batches, generic BTCs (PMNT/MCOP/OTHR), different versions from one bank to another, and remittance data lost when one link in the chain still runs on MT. Each bank must therefore be tested with live files before matching rules are rolled out across the board.

A pragmatic adoption strategy in 2026 is to switch incoming reporting to camt.053/054 wherever the bank offers it, keeping CFONB120 or MT940 as a fallback feed for one quarter. It also means requiring meaningful EndToEndId values on every batch you send, then rebuilding the accounting routing rules on BTCs.