MT940 Statement Parser
Turn a SWIFT MT940 bank statement into clean JSON or a CSV transaction table — opening/closing balances, value & entry dates, debit/credit, amounts, references and narrative. Runs entirely in your browser, nothing is uploaded.
Read a SWIFT MT940 statement without a spreadsheet macro
Paste a MT940 bank statement — the tagged-field SWIFT format your bank exports as
.sta, .mt940, .940 or .txt — and this tool turns it into structured JSON or a
flat CSV transaction table. Everything runs locally with WebAssembly, so your
statement never leaves your browser.
It reads the fields banks actually send:
:20:/:25:/:28C:— statement reference, account identification, and statement number.:60F:/:62F:/:64:/:65:— opening, closing, available and forward-available balances, each with its currency and debit/credit sign.:61:— every statement line: value date and entry date, the C/D/RC/RD debit-credit mark, the amount, the 4-character transaction-type code (NTRF,NMSC,NDDT, …), and the customer and bank references split on//.:86:— the narrative attached to each transaction, kept intact even across multiple lines.
Multi-statement files (several :20: blocks in one export) are handled — in CSV each row
carries its Statement number so nothing is merged by accident.
Worked example
This statement:
:20:REF12345
:25:NL91ABNA0417164300
:28C:00123/001
:60F:C240101EUR1000,00
:61:2401020102D150,50NTRFNONREF//BANKREF1
:86:Payment to Acme Corp invoice 42
:61:2401030103C2000,00NTRFPAYROLL//BANKREF2
:86:Salary March
:62F:C240131EUR2849,50
as CSV becomes:
Statement,Value Date,Entry Date,D/C,Amount,Currency,Transaction Type,Customer Reference,Bank Reference,Description
1,2024-01-02,2024-01-02,D,-150.50,EUR,NTRF,NONREF,BANKREF1,Payment to Acme Corp invoice 42
1,2024-01-03,2024-01-03,C,2000.00,EUR,NTRF,PAYROLL,BANKREF2,Salary March
The debit line is signed negative, the credit positive, the 240102 dates are expanded to
ISO, and each :86: narrative lands on its own row. Switch to JSON to also get the
opening/closing/available balances as structured objects.
FAQ
What is an MT940 file?
MT940 is the SWIFT Customer Statement Message — the standard end-of-day bank statement
format. It is plain text made of colon-delimited tags (:20:, :61:, :86:, …) rather than
columns, which is why it needs parsing before it opens cleanly in a spreadsheet.
Is my bank data uploaded anywhere?
No. The parser is compiled to WebAssembly and runs entirely in your browser — the statement text is never sent to a server, logged, or stored.
Why are some amounts negative?
With Sign amounts on (the default), a debit (D/RD) is written as a negative number and
a credit (C/RC) as positive, so a column of amounts sums to the net movement. Turn the
toggle off to keep every amount positive and rely on the D/C column for direction instead.
What's the difference between the value date and the entry date?
The value date is when the money is credited/debited for interest purposes (the 6-digit
YYMMDD at the start of :61:); the entry date is when the bank booked it (the optional
4-digit MMDD that follows). When the entry date omits the year, this tool borrows it from the
value date so both render as full dates.
Does it handle files with several statements?
Yes. Each :20: starts a new statement. In JSON you get an array of statement objects; in CSV
every transaction row includes a Statement column (1, 2, 3, …) so lines from different
statements stay distinguishable.
Can I get an Excel file?
Choose CSV and open it directly in Excel, Google Sheets or Numbers — a CSV imports as columns with no extra step. Pick the delimiter your locale expects (comma or semicolon) so the columns split correctly.
Limits & edge cases
- Amounts use the SWIFT comma decimal (
1234,56); they are parsed and re-emitted with two decimal places in CSV. Balances keep their currency from the:60F:opening balance. - Balances live in the JSON output; the CSV is a flat transaction table (with a
Statementcolumn) so it imports cleanly into a sheet. - SWIFT block headers (
{1:…}{4:…}) and the block-4-trailer are ignored, so you can paste either the raw wire message or just the tag lines. - Unrecognized tags (like
:21:) are skipped rather than causing an error; a genuinely malformed balance or:61:line reports a clear message instead of failing silently.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool mt940-statement-parse ":20:REF12345
:25:NL91ABNA0417164300
:28C:00123/001
:60F:C240101EUR1000,00
:61:2401020102D150,50NTRFNONREF//BANKREF1
:86:Payment to Acme Corp invoice 42
:62F:C240131EUR849,50"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/mt940-statement-parse/?data=%3A20%3AREF12345%0A%3A25%3ANL91ABNA0417164300%0A%3A28C%3A00123%2F001%0A%3A60F%3AC240101EUR1000%2C00%0A%3A61%3A2401020102D150%2C50NTRFNONREF%2F%2FBANKREF1%0A%3A86%3APayment%20to%20Acme%20Corp%20invoice%2042%0A%3A62F%3AC240131EUR849%2C50&output=json&date_format=iso&delimiter=comma&signed_amounts=trueMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
