Camt053 is a Python library for reading ISO 20022 camt Bank-to-Customer Statements (camt.053/052/054) and generating validated reversing entries by return reason code (e.g. AC04 Closed Account).
Project description
camt053: ISO 20022 Bank Statements and Reversing Entries
Read ISO 20022 camt Bank-to-Customer Cash Management messages, extract
booked entries by return reason code (e.g. AC04 Closed Account), and generate
validated reversing entries — the core of a modern, AI-assisted treasury
stack with native MCP and LSP integrations.
Latest release: v0.0.1 — namespace-agnostic camt.052/053/054 parsing and one-shot reversing-entry generation, validated against the official ISO 20022
camt.053.001.14schema, for Python 3.10+. See what's new →
Contents
- Overview
- Install
- Quick Start
- Features
- Usage
- Supported messages
- Architecture
- Examples
- Development
- License
- Contributing
- Acknowledgements
Overview
camt053 reads ISO 20022 camt cash-management messages — the standardised
bank-to-customer statements (camt.053), account reports (camt.052), and
debit/credit notifications (camt.054) — into a typed model, lets you filter
booked entries by ISO external return reason code, and generates a validated
reversing entry for the matching transactions.
The headline capability is the one-shot reversing-entry workflow: read an incoming camt.053 statement, find the entries carrying a return reason code (e.g. AC04 Closed Account), and emit a validated reversing entry — answering the prompt-engineering dream:
"Read this incoming bank statement XML, parse out the transactions with error code AC04, and automatically generate the reversing entry."
- Website: https://camt053.com
- Source code: https://github.com/sebastienrousseau/camt053
- Bug reports: https://github.com/sebastienrousseau/camt053/issues
A single shared facade (camt053.services) backs four developer surfaces — the
Python API, the CLI, the REST API, and the companion MCP and LSP servers — so
every interface behaves identically. This package is part of the camt053
suite (all Python 3.10+):
| Package | Role |
|---|---|
camt053 |
Core library + Click CLI + FastAPI REST API (this package) |
camt053-mcp |
Model Context Protocol server (for AI agents) |
camt053-lsp |
Language Server Protocol server (for editors) |
flowchart LR
A["Inbound camt.05x XML"] -->|parse| B["camt053.services"]
B -->|filter by reason code| C["AC04 entries"]
C -->|reverse + validate| D["camt.053.001.14 reversing entry"]
Install
camt053 runs on macOS, Linux, and Windows and requires Python 3.10+ and pip.
python -m pip install camt053
Using an isolated virtual environment (recommended)
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
python -m pip install -U camt053
Quick Start
from camt053 import services
# An incoming camt.053 statement (truncated for brevity — see examples/).
statement_xml = open("statement.xml", encoding="utf-8").read()
# Find the entries returned AC04 (Closed Account).
ac04 = services.filter_entries(statement_xml, "AC04")
print(f"{len(ac04)} AC04 entr{'y' if len(ac04) == 1 else 'ies'}")
# Generate the reversing entry: parse -> filter -> reverse, in one call.
reversal_xml = services.generate_reversal(statement_xml, reason_code="AC04")
print(reversal_xml) # validated camt.053.001.14 document
Or from the command line:
# Generate a reversing entry for every AC04 entry on a statement
camt053 reverse -i statement.xml -r AC04 -o reversal.xml
# List the entries on a statement (optionally filtered by reason)
camt053 entries -i statement.xml -r AC04
# Inspect the parsed statement as JSON, or validate an identifier
camt053 parse -i statement.xml
camt053 validate-id -k iban -v GB29NWBK60161331926819
parse, entries, and reverse accept -i - to read from stdin, so they
compose in a pipeline.
Features
- Parse camt.053 / camt.052 / camt.054 into a typed, JSON-serialisable
model. Parsing is namespace-agnostic, so every ISO version (
.001.01through.001.14) and real-world bank file is read. - Filter booked entries by ISO external return reason code (AC04, AC06, MD07, …).
- Reverse — generate a
camt.053.001.14reversing entry from the matching entries (credit/debit indicator flipped,RvslIndset, return reason carried inRtrInf), in one call. - Validated output — generated reversals are checked against the official
ISO 20022
camt.053.001.14XSD bundled with the package. - Safe by default — XML is parsed with
defusedxml(XXE / billion-laughs safe); output paths are traversal-checked. - One facade, four interfaces — the CLI, REST API, MCP server, and LSP
server all call
camt053.services. - IBAN / BIC / LEI validators (ISO 13616 / 9362 / 17442).
- Typed (mypy
--strict) and tested (100% coverage), validated against the official ISO 20022 business samples.
Usage
from camt053 import parse_statement, services
# A minimal incoming camt.053 statement: a EUR 1,500 credit transfer that was
# booked, then returned because the beneficiary account was closed (AC04).
statement_xml = """<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.14">
<BkToCstmrStmt>
<GrpHdr><MsgId>STMT-MSG-0001</MsgId><CreDtTm>2026-06-15T08:00:00</CreDtTm></GrpHdr>
<Stmt>
<Id>STMT-0001</Id><CreDtTm>2026-06-15T08:00:00</CreDtTm>
<Acct><Id><IBAN>GB29NWBK60161331926819</IBAN></Id><Ccy>EUR</Ccy></Acct>
<Bal><Tp><CdOrPrtry><Cd>CLBD</Cd></CdOrPrtry></Tp>
<Amt Ccy="EUR">10000.00</Amt><CdtDbtInd>CRDT</CdtDbtInd>
<Dt><Dt>2026-06-15</Dt></Dt></Bal>
<Ntry>
<NtryRef>NTRY-0001</NtryRef>
<Amt Ccy="EUR">1500.00</Amt><CdtDbtInd>CRDT</CdtDbtInd>
<Sts><Cd>BOOK</Cd></Sts>
<NtryDtls><TxDtls>
<RtrInf><Rsn><Cd>AC04</Cd></Rsn></RtrInf>
</TxDtls></NtryDtls>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>"""
# 1. Parse into the typed model.
statement = parse_statement(statement_xml)
print(statement.account.identifier()) # -> GB29NWBK60161331926819
print(len(statement.entries)) # -> 1
# 2. Select the entries returned AC04 (Closed Account).
ac04 = statement.entries_with_reason("AC04")
print(ac04[0].amount, ac04[0].credit_debit_indicator) # -> 1500.00 CRDT
# 3. Generate the validated reversing entry (the original CRDT becomes DBIT).
reversal_xml = services.generate_reversal(statement_xml, reason_code="AC04")
assert "<RvslInd>true</RvslInd>" in reversal_xml
assert "<CdtDbtInd>DBIT</CdtDbtInd>" in reversal_xml
Supported messages
| Message type | Name | Direction |
|---|---|---|
camt.052.001.14 |
Bank To Customer Account Report | read |
camt.053.001.14 |
Bank To Customer Statement | read + reverse |
camt.054.001.14 |
Bank To Customer Debit Credit Notification | read |
The parser is namespace-agnostic and reads every ISO version of these messages;
the official XSDs for .001.01–.001.14 are bundled under camt053/xsd/.
Reversing entries are emitted as camt.053.001.14.
Architecture
flowchart TD
CLI["Click CLI"] --> S["camt053.services"]
API["FastAPI REST API"] --> S
MCP["camt053-mcp"] --> S
LSP["camt053-lsp"] --> S
S --> P["parse/ — statement_parser, reason_codes"]
S --> R["reversal/ — reversal builder"]
S --> X["xml/ — template + official ISO XSD"]
S --> V["validation/ — IBAN, BIC, LEI, JSON Schema"]
| Module | Responsibility |
|---|---|
camt053.parse |
Namespace-agnostic statement parser and return-reason helpers |
camt053.reversal |
Builds flat reversing-entry records from parsed entries |
camt053.xml |
Renders the camt.053 reversal template and validates it via the ISO XSD |
camt053.validation |
IBAN / BIC / LEI and JSON-Schema validators |
camt053.security |
XXE-safe parsing and path-traversal-checked output |
camt053.services |
The shared facade backing every interface |
Examples
Runnable, self-contained scripts live in examples/:
| Example | Demonstrates |
|---|---|
reverse_ac04.py |
The headline workflow — find AC04 entries and generate the reversing entry |
parse_statement.py |
Parsing a statement into the typed model |
services_facade.py |
The shared camt053.services facade |
validate_identifiers.py |
IBAN / BIC / LEI validation |
rest_api_client.py |
Driving the FastAPI REST API in-process |
git clone https://github.com/sebastienrousseau/camt053.git && cd camt053
python examples/reverse_ac04.py
Development
git clone https://github.com/sebastienrousseau/camt053.git && cd camt053
mise install
poetry install
poetry shell
A Makefile orchestrates the quality gates (kept in lockstep with CI):
make check # all gates (REQUIRED before commit)
make test # pytest with coverage (100% gate)
make lint # ruff + black --check
make type-check # mypy --strict
make examples # run the example scripts
License
Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.
Contributing
Contributions are welcome — see the contributing instructions. Thanks to all contributors.
Acknowledgements
Built on Click,
Rich, Jinja2,
xmlschema,
defusedxml, and
FastAPI, against the official ISO 20022
camt.05x schemas.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file camt053-0.0.1.tar.gz.
File metadata
- Download URL: camt053-0.0.1.tar.gz
- Upload date:
- Size: 385.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
911f77e7da8c87d9398c485d86148bbec3f9e019239c7b1340b65f142b8ba519
|
|
| MD5 |
43f56a8f98c76bf7688eca0efc074a41
|
|
| BLAKE2b-256 |
11deef7e3cf4241638ff7848dbf1007edd21e2bec261e454e19eacdeb47c9746
|
Provenance
The following attestation bundles were made for camt053-0.0.1.tar.gz:
Publisher:
release.yml on sebastienrousseau/camt053
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
camt053-0.0.1.tar.gz -
Subject digest:
911f77e7da8c87d9398c485d86148bbec3f9e019239c7b1340b65f142b8ba519 - Sigstore transparency entry: 1853957315
- Sigstore integration time:
-
Permalink:
sebastienrousseau/camt053@67614d8401cb0b4dc9282daca192e4ec0e833bb9 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@67614d8401cb0b4dc9282daca192e4ec0e833bb9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file camt053-0.0.1-py3-none-any.whl.
File metadata
- Download URL: camt053-0.0.1-py3-none-any.whl
- Upload date:
- Size: 443.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b71c37a797135873b7f62313cf8ffa4e1dcd6ebcc8a1b8835f9c4764ca6776f
|
|
| MD5 |
2686fa7c68e88f21d7b109f12103aa2f
|
|
| BLAKE2b-256 |
7287e87703fde94ed5a085d6291a58d25d0448c4789cf62b27ddb3d885fb6547
|
Provenance
The following attestation bundles were made for camt053-0.0.1-py3-none-any.whl:
Publisher:
release.yml on sebastienrousseau/camt053
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
camt053-0.0.1-py3-none-any.whl -
Subject digest:
7b71c37a797135873b7f62313cf8ffa4e1dcd6ebcc8a1b8835f9c4764ca6776f - Sigstore transparency entry: 1853957332
- Sigstore integration time:
-
Permalink:
sebastienrousseau/camt053@67614d8401cb0b4dc9282daca192e4ec0e833bb9 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@67614d8401cb0b4dc9282daca192e4ec0e833bb9 -
Trigger Event:
push
-
Statement type: