CAMT files are XML reports that banks use to transmit financial transactions and balances. Think of your bank statement, but in a standardized digital format. The idea is that software can more easily read these files and process them automatically.
Different Versions
There are different “flavors” of CAMT files, each serving a different purpose:
-
camt.052: Mainly covers intraday transactions (interim balances throughout the day).
-
camt.053: This is your daily or periodic bank statement.
-
camt.054: Provides notifications of individual credits and debits (credit and debit notifications).
They are quite similar in structure, but the content and timing differ. In general, CAMT.053 (the “End-of-Day Statement”) is the most suitable for audit purposes because this type provides a complete overview of all transactions and the ending balance for a specific period (usually daily).
While CAMT.052 (intraday) and CAMT.054 (notifications) can also be useful for identifying or tracking transactions throughout the day, these messages are generally less suitable as a formal source for audits. After all, they do not provide a ‘closed’ period overview but rather (interim) status reports or notifications.
Which Banks Use CAMT?
Many European banks now support CAMT standards. In the Netherlands, banks like ING, Rabobank, and ABN AMRO offer it as a replacement for the old MT940 standard. You also see major banks in other European countries increasingly distributing CAMT reports. The idea is to have a uniform standard so that companies and accountants do not have to deal with different file formats each time.
Disadvantages of Batch Details
However, not everything is perfect. Sometimes transactions are grouped in a batch. For example, if you make several online purchases on the same day from one party, those payments may appear bundled in your CAMT file. You would then see one total amount instead of multiple individual transactions. This can be inconvenient if you want to know exactly which payments are included in that “combined” amount.
Often, when making such batch payments in the bank, a SEPA file must be imported. It is advisable not to delete this file; you can often still link it later with a CAMT file to view the details.
CAMT to CSV or Excel
When you open a CAMT file, it may not immediately make much sense. That’s why many people look for a suitable way to convert it. Below is a simple Python script. It’s not extremely sophisticated, but it demonstrates the principle. You will still need some XML knowledge, especially because CAMT files often have namespaces (such as urn:iso:std:iso:20022:tech:xsd:camt.053.001.02
). You need to check which namespace is in your CAMT file and adjust accordingly.
import pandas as pd
import xml.etree.ElementTree as ET
import os
def parse_camt_to_dataframe(camt_file):
# Parses a CAMT 053 file and returns a pandas DataFrame
# with the relevant columns.
#:param camt_file: Path to the CAMT XML file.
#:return: pandas.DataFrame with all extracted transactions.
if not os.path.exists(camt_file):
raise FileNotFoundError(f"The CAMT file {camt_file} was not found.")
# Parse the XML file
try:
tree = ET.parse(camt_file)
root = tree.getroot()
except ET.ParseError as e:
raise ValueError(f"Error reading XML: {e}")
# This is an example namespace (adjust if your CAMT requires it).
ns = '{urn:iso:std:iso:20022:tech:xsd:camt.053.001.02}'
# Statement-level information (optional)
# IBAN of the own account
statement_iban_elem = root.find(f'.//{ns}Rpt/{ns}Acct/{ns}Id/{ns}IBAN')
statement_iban = statement_iban_elem.text if statement_iban_elem is not None else ''
# Find all entries
entries = root.findall(f'.//{ns}Ntry')
# Store data in a list of dicts to convert to a DataFrame later
transaction_records = []
for entry in entries:
# Booking date
booking_date_elem = entry.find(f'.//{ns}BookgDt/{ns}Dt') or entry.find(f'.//{ns}BookgDt/{ns}DtTm')
booking_date = booking_date_elem.text if booking_date_elem is not None else ''
# Value date
value_date_elem = entry.find(f'.//{ns}ValDt/{ns}Dt') or entry.find(f'.//{ns}ValDt/{ns}DtTm')
value_date = value_date_elem.text if value_date_elem is not None else ''
# Amount & currency
amount_elem = entry.find(f'.//{ns}Amt')
amount = amount_elem.text if amount_elem is not None else ''
currency = amount_elem.attrib.get('Ccy', '') if amount_elem is not None else ''
# Credit or debit
cdt_dbt_elem = entry.find(f'.//{ns}CdtDbtInd')
credit_debit = cdt_dbt_elem.text if cdt_dbt_elem is not None else ''
# Bank transaction code (BkTxCd)
bank_tx_code_elem = entry.find(f'.//{ns}BkTxCd/{ns}Domn/{ns}Fmly/{ns}SubFmlyCd')
bank_tx_code = bank_tx_code_elem.text if bank_tx_code_elem is not None else ''
record = {
'Statement IBAN': statement_iban,
'Booking Date': booking_date,
'Value Date': value_date,
'Amount': amount,
'Currency': currency,
'Credit/Debit': credit_debit,
'Bank Transaction Code': bank_tx_code,
}
transaction_records.append(record)
# Convert list of dicts into a DataFrame
df = pd.DataFrame(transaction_records)
return df
def convert_camt_to_csv_and_excel(camt_file, csv_file='output.csv', excel_file='output.xlsx'):
df = parse_camt_to_dataframe(camt_file)
# Export to CSV
df.to_csv(csv_file, index=False, encoding='utf-8')
print(f"CSV file saved as: {csv_file}")
# Export to Excel
df.to_excel(excel_file, index=False)
print(f"Excel file saved as: {excel_file}")
# Example how to use it:
# if __name__ == "__main__":
# convert_camt_to_csv_and_excel('dummy_camt053.xml', 'dummy_output.csv', 'dummy_output.xlsx')
Now you can easily convert CAMT files into readable formats for further processing.