# Quickstart: from bank statement to validated reversing entry in 10 minutes
This guide walks you from "the bank sent me a camt.053 statement with a
returned payment on it" to "I have a validated ISO 20022 reversing entry"
in five short steps. No prior ISO 20022 knowledge required.
If you already know what camt.053 is and just want the CLI flags, skip to
the [README](https://github.com/sebastienrousseau/camt053#quick-start).
---
## Prerequisites
- Python 3.10 or later
- 10 minutes
- A terminal
That's it. You won't need a bank account, a sandbox, or an ISO 20022 spec
PDF. Everything the tutorial needs ships inside the package (including the
official XSD schemas the validation runs against).
## Step 1: Install
```bash
pip install camt053
```
Verify:
```bash
camt053 -V
# -> Camt053, version 0.0.13
```
If you'd rather not pollute your global Python environment:
```bash
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
pip install camt053
```
## Step 2: See what camt053 can do
```bash
camt053 -h
```
You'll see a command suite: `parse`, `entries`, `validate`, `reverse`,
`reasons`, `classify`, `message-types`, `validate-id`,
`check-cbpr-readiness`. We'll use five of them.
List the message families the library reads:
```bash
camt053 message-types
```
Output:
```text
Supported message types
Message type Name
──────────────────────────────────────────────────────────────
camt.052.001.14 Bank To Customer Account Report
camt.053.001.14 Bank To Customer Statement
camt.054.001.14 Bank To Customer Debit Credit Notification
```
And the ISO return reason codes it knows (41 of them), each with the
handling action the built-in policy assigns:
```bash
camt053 reasons
```
```text
Return reason codes
Code Name Action
──────────────────────────────────────────────────────────
AC01 Incorrect Account Number return
AC02 Invalid Debtor Account Number return
AC03 Invalid Creditor Account Number return
AC04 Closed Account Number return
...
TM01 Cut Off Time retry
```
`AC04` (Closed Account Number) is the tutorial's return reason: a payment
you sent bounced because the beneficiary account was closed, and your bank
reported it back on your statement.
## Step 3: Get a statement to work with
Real statements come from your bank channel (EBICS, SFTP, portal
download). For the tutorial, save this minimal but fully schema-valid
camt.053.001.14 statement as `statement.xml`. It carries one booked EUR
1,500 credit that was returned with reason `AC04`:
```xml
STMT-MSG-00012026-06-15T08:00:00
STMT-0001
2026-06-15T08:00:00
GB29NWBK60161331926819
EUR
Acme Treasury Ltd
CLBD
10000.00CRDT
2026-06-15
NTRY-0001
1500.00CRDT
BOOK
2026-06-14
2026-06-14
PMNTRCDTRRTN
E2E-0001
AC04
```
First thing to do with any incoming file: validate it against the official
ISO XSD (bundled with the package, no download needed):
```bash
camt053 validate -i statement.xml
```
```text
✓ Valid camt.053.001.14
```
## Step 4: Inspect the statement
See the entries, filtered down to the AC04 returns:
```bash
camt053 entries -i statement.xml -r AC04
```
```text
Statement entries
Reference Amount Ccy Cr/Dr Reason
────────────────────────────────────────────
NTRY-0001 1500.00 EUR CRDT AC04
1 entry.
```
Or dump the whole parsed statement as JSON (group header, account,
balances, entries), ready for `jq` or your pipeline:
```bash
camt053 parse -i statement.xml
```
```text
{
"message_type": "camt.053.001.14",
"msg_id": "STMT-MSG-0001",
"creation_date_time": "2026-06-15T08:00:00",
"statements": [ ... ]
}
```
## Step 5: Generate the reversing entry
The headline command. Find every AC04 entry and emit a validated
camt.053.001.14 reversing-entry document:
```bash
camt053 reverse -i statement.xml -r AC04 -o reversal.xml
```
```text
✓ Reversing entry written to reversal.xml
```
Look at what it wrote:
```bash
head -12 reversal.xml
```
```xml
RVSL-STMT-0001
2026-06-15T08:00:00
RVSL-STMT-0001
```
The reversing entry mirrors the original booked entry with the
credit/debit indicator flipped (`CRDT` becomes `DBIT`), `RvslInd` set,
a stable `RVSL-` reference derived from the original (same input, same
output, every time), and the AC04 return reason carried in `RtrInf`.
It is XSD-validated before it is written; prove it to yourself:
```bash
camt053 validate -i reversal.xml
```
```text
✓ Valid camt.053.001.14
```
Prefer Python? The same workflow is three lines through the shared
services facade (the CLI, REST API, and MCP/LSP servers all call the
same functions):
```python
from camt053 import services
xml = open("statement.xml", encoding="utf-8").read()
ac04 = services.filter_entries(xml, "AC04") # 1 entry
reversal = services.generate_reversal(xml, reason_code="AC04")
```
## What you just learned
- `camt053 validate` - XSD pre-flight for any incoming file (use this every time)
- `camt053 entries` / `camt053 parse` - inspect what the bank sent
- `camt053 reverse` - generate the validated reversing entry
- `camt053 reasons` / `message-types` - the built-in reference data
That's 80% of the surface for 90% of users.
## Where to go next
| If you want to... | Read |
| :--- | :--- |
| Reverse a whole directory of statements at once | `camt053 reverse --batch` ([`examples/generate_batch.py`](https://github.com/sebastienrousseau/camt053/blob/main/examples/generate_batch.py)) |
| Emit a pacs.004 PaymentReturn instead of camt.053 | `camt053 reverse --output-format pacs004` |
| Run camt053 as a REST service | `uvicorn camt053.api.app:app` ([README Usage](https://github.com/sebastienrousseau/camt053#usage)) |
| Pre-flight the Nov 14-16 2026 CBPR+ cutover | `camt053 check-cbpr-readiness` ([version matrix](version-matrix.md)) |
| Stream very large statements with bounded memory | [`examples/stream_entries.py`](https://github.com/sebastienrousseau/camt053/blob/main/examples/stream_entries.py) |
| Deploy the REST API with Redis + Prometheus + Grafana | [Deployment cookbook](deployment-cookbook.md) |
| Wire camt053 into an AI assistant (Claude Desktop, etc.) | `pip install camt053-mcp` |
| See every public function exercised in a runnable script | [`examples/`](https://github.com/sebastienrousseau/camt053/tree/main/examples) |
## Troubleshooting
| Symptom | Likely cause | Fix |
| :--- | :--- | :--- |
| `camt053: command not found` | Install went to a directory not on `PATH` | Re-install in a venv (see Step 1) |
| `✗ Invalid camt.053.001.14` on a file your bank sent | Bank emits an older revision (.02, .08) | camt053 detects the version from the namespace; run `camt053 parse` (parsing accepts all revisions), and see the [version matrix](version-matrix.md) |
| `No statement entries match return reason AC04` | The statement has no entry with that reason | Run `camt053 entries -i ` (no `-r`) to see which reasons are present |
| `XML payload contains a DOCTYPE or ENTITY declaration` | The file carries a DTD (or an XXE attempt) | Deliberate: the security guard refuses inline DTDs; re-export the file without a DOCTYPE |
| Reversal amounts look re-ordered / reformatted | They aren't | Amounts are carried as strings end to end and rendered byte-for-byte; diff the `Amt` elements |
## Stuck?
- [Open an issue](https://github.com/sebastienrousseau/camt053/issues/new/choose)
with the CLI invocation that failed plus the error output.
- See [SUPPORT.md](https://github.com/sebastienrousseau/camt053/blob/main/SUPPORT.md) for the full support matrix.
---
*Found a confusing bit in this tutorial? PRs to
[`docs/quickstart.md`](https://github.com/sebastienrousseau/camt053/blob/main/docs/quickstart.md)
are the most useful thing a new user can contribute. You spot the sharp
edges that long-time users no longer see.*