Automate bank statement reconciliation by matching SWIFT MT940 payment lines against CSV payment reports using date, amount, and virtual account number.
date + amount + va_number
Payment credits with VA numbers only. Fee/debit lines are excluded from stats.
Bank mutation file: TGL_TRAN, MUTASI_KREDIT/MUTASI_DEBET, DESK_TRAN
Google Data Studio payment report: Payment Date, Total Paid Amount, Virtual Account Number
When enabled, only rows with amount > 0 are compared on MT940, bank mutation export, and GDS.
Multipart form upload with mt940_file and mutation_csv_file (plus gds_csv_file for full mode).
Protected endpoints require an API key in the request header:
X-API-Key: your-secret-key
Set the server environment variable RECONCILE_API_KEY to the expected value.
Liveness probe for load balancers and Docker health checks.
{ "status": "ok" }
Returns active CSV column mapping, MT940 detail fields, and reconciliation settings.
Upload MT940 and bank mutation export, run reconciliation, and receive JSON summary plus result rows.
Query: status=all|matched|mt940_only|mutation_only|duplicate · credits_only=true|false
curl -X POST "http://localhost:8000/api/v1/reconcile?credits_only=true" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv"
Run reconciliation and download a multi-sheet Excel report.
curl -X POST "http://localhost:8000/api/v1/reconcile/export/xlsx" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv" \ -o reconciliation_report.xlsx
Export a filtered result set as CSV.
Query: status=matched|mt940_only|mutation_only|duplicate
curl -X POST "http://localhost:8000/api/v1/reconcile/export/csv?status=mutation_only" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv" \ -o unmatched_mutation.csv
Full reconciliation: MT940 + bank mutation export (bank truth) vs GDS export (Google Data Studio). Returns bank alignment, MT940 vs GDS, mutation vs GDS, and consolidated missing-from-GDS rows.
Query: bank_status · mt940_gds_status · mutation_gds_status · credits_only=true|false
curl -X POST "http://localhost:8000/api/v1/reconcile/full?credits_only=true" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv" \ -F "gds_csv_file=@gds_export.csv"
Run full reconciliation and download a multi-sheet Excel report (bank + GDS gap sheets).
curl -X POST "http://localhost:8000/api/v1/reconcile/full/export/xlsx" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv" \ -F "gds_csv_file=@gds_export.csv" \ -o full_reconciliation_report.xlsx
Export a filtered full-reconciliation result set as CSV.
Query: section=missing_from_gds|gds_only|bank_matched|bank_mt940_only|bank_mutation_only|mt940_gds_matched|mt940_missing_from_gds|mutation_gds_matched|mutation_missing_from_gds
curl -X POST "http://localhost:8000/api/v1/reconcile/full/export/csv?section=missing_from_gds" \ -H "X-API-Key: your-secret-key" \ -F "mt940_file=@statement.mt940" \ -F "mutation_csv_file=@mutation_export.csv" \ -F "gds_csv_file=@gds_export.csv" \ -o missing_from_gds.csv
Bank-only (/reconcile):
matched_count — rows found on both sidescsv_match_rate — matched / bank mutation export transactionsmt940_match_rate — matched / MT940 payment linesmt940_only_count — in MT940 but not mutation exportmutation_only status — in mutation export but not MT940Full reconciliation (/reconcile/full):
summary.bank_matched_count — MT940 ↔ mutation export alignedsummary.mt940_missing_from_gds_count — bank (MT940) not in GDSsummary.mutation_missing_from_gds_count — bank (mutation export) not in GDSsummary.consolidated_missing_count — unique bank-only rows missing from GDSsummary.gds_only_count — recorded in GDS but not in bankmt940_gds.results — each row has mt940 + gdsmutation_gds.results — each row has mutation + gdsmissing_from_gds — consolidated alert list with sources (mt940 and/or mutation)