TL;DR - Quick Summary
- Who it is for: Developers building fintech apps, accounting automation, lending tools, or analytics pipelines from bank statement data.
- Structure: The JSON includes account metadata, the statement period, opening and closing balances, and a transactions array with ISO 8601 dates and signed amounts.
- Watch out for: Store amounts as integer cents or a decimal type, not floats, or summed totals can drift from the closing balance.
- Completeness check: Confirm that the opening balance plus the sum of all transactions equals the closing balance before accepting a file.
- Start: Convert your statement at /pdf-to-json.
JSON Format for Bank Statements
JSON (JavaScript Object Notation) is the ideal format for programmatic access to bank statement data. Unlike CSV files that require column mapping, JSON provides structured, hierarchical data with explicit types, making it perfect for API integrations, application development, and automated financial processing.
Why JSON for Bank Statement Data?
Structured Data
Hierarchical format with nested objects for accounts, transactions, and metadata
Advantage: Easy to parse and navigate programmatically
Type Safety
Explicit data types (strings, numbers, booleans, arrays, objects)
Advantage: Reduces parsing errors and data validation issues
Universal Format
Supported natively by virtually all programming languages and platforms
Advantage: No special libraries needed for basic parsing
API-Friendly
Standard format for REST APIs and microservices communication
Advantage: Seamless integration with modern web architectures
Human-Readable
Text-based format that's easy to read and debug
Advantage: Simplifies development and troubleshooting
Extensible
Easy to add custom fields without breaking existing parsers
Advantage: Future-proof for evolving requirements
JSON Bank Statement Structure
Standard JSON Format
Our JSON output follows a consistent structure optimized for common use cases. The format includes account metadata, statement period, balance information, detailed transactions, and summary statistics.
{
"account": {
"accountNumber": "****1234",
"accountType": "checking",
"bankName": "Example Bank",
"currency": "USD"
},
"statementPeriod": {
"startDate": "2026-01-01",
"endDate": "2026-01-31"
},
"balances": {
"openingBalance": 5234.56,
"closingBalance": 6789.12,
"averageBalance": 5987.43
},
"transactions": [
{
"id": "txn_001",
"date": "2026-01-15",
"description": "PAYROLL DEPOSIT - ACME CORP",
"amount": 3500,
"type": "credit",
"balance": 8734.56,
"category": "income"
},
{
"id": "txn_002",
"date": "2026-01-16",
"description": "PURCHASE - AMAZON.COM",
"amount": -52.99,
"type": "debit",
"balance": 8681.57,
"category": "shopping"
}
],
"summary": {
"totalCredits": 4500,
"totalDebits": -2945.44,
"transactionCount": 47
}
}Top-Level Fields
account- Account metadata and identifiersstatementPeriod- Date range coveredbalances- Opening, closing, and averagetransactions- Array of all transactionssummary- Aggregate statistics
Transaction Fields
id- Unique transaction identifierdate- ISO 8601 date (YYYY-MM-DD)description- Transaction descriptionamount- Signed number (- for debit)type- "credit" or "debit"category- Auto-categorized type
Developer Use Cases
Fintech Applications
Banking apps, personal finance management, budgeting tools
Key Benefits:
- β’Automatic transaction categorization
- β’Real-time balance updates
- β’Spending pattern analysis
- β’Integration with budgeting features
Lending & Underwriting
Loan applications, credit decisioning, income verification
Key Benefits:
- β’Automated income calculation
- β’Cash flow analysis for creditworthiness
- β’Debt-to-income ratio computation
- β’Fraud detection algorithms
Accounting Automation
Bookkeeping software, expense tracking, reconciliation
Key Benefits:
- β’Automatic bank feed import
- β’Transaction matching and categorization
- β’Multi-account reconciliation
- β’Integration with ERP systems
Data Analytics & BI
Financial dashboards, business intelligence, reporting
Key Benefits:
- β’Structured data for analysis pipelines
- β’Easy integration with data warehouses
- β’Visualization tool compatibility
- β’Machine learning model training
Convert Bank Statements to JSON
Transform PDF bank statements into structured JSON format for your applications. Perfect for API integration, data processing pipelines, and automated financial workflows.
Convert PDF to JSONWays to Get the JSON
Single File Download
SimpleUpload a statement at /pdf-to-json and download the JSON file. Works on the free tier: 1 conversion per 24 hours up to 5 pages, or 2 up to 10 pages with a free account.
Bulk Upload
ModeratePaid plans upload 10 (Professional), 25 (Business), or 50 (Enterprise) statements in one batch, with 1,000, 2,000, or 4,000 pages per month.
API Access
AdvancedAPI access is part of the Enterprise plan. There is no public API documentation; contact the team to discuss your pipeline.
π‘ Ingestion Best Practices
- β’ Validate JSON schema before processing to catch format issues early
- β’ Check that opening balance plus transactions equals closing balance
- β’ Deduplicate when statement periods overlap
- β’ Keep the source PDF alongside the JSON for audit questions
Code Examples
JavaScript (Node.js)
Process JSON bank statement and calculate metrics
const fs = require('fs');
// Load JSON bank statement
const statement = JSON.parse(fs.readFileSync('statement.json'));
// Calculate total income
const totalIncome = statement.transactions
.filter(t => t.type === 'credit')
.reduce((sum, t) => sum + t.amount, 0);
// Calculate total expenses
const totalExpenses = statement.transactions
.filter(t => t.type === 'debit')
.reduce((sum, t) => sum + Math.abs(t.amount), 0);
// Group by category
const byCategory = statement.transactions.reduce((acc, t) => {
acc[t.category] = (acc[t.category] || 0) + Math.abs(t.amount);
return acc;
}, {});
console.log('Income:', totalIncome);
console.log('Expenses:', totalExpenses);
console.log('By Category:', byCategory);Python
Pandas DataFrame for analysis
import json
import pandas as pd
# Load JSON statement
with open('statement.json') as f:
statement = json.load(f)
# Convert transactions to DataFrame
df = pd.DataFrame(statement['transactions'])
# Convert date to datetime
df['date'] = pd.to_datetime(df['date'])
# Add month column
df['month'] = df['date'].dt.to_period('M')
# Monthly summary
monthly_summary = df.groupby('month')['amount'].agg([
('total', 'sum'),
('count', 'count'),
('avg', 'mean')
])
print(monthly_summary)Ruby
Process and categorize transactions
require 'json'
# Load JSON statement
statement = JSON.parse(File.read('statement.json'))
# Filter transactions by amount
large_transactions = statement['transactions'].select { |t|
t['amount'].abs > 1000
}
# Group by type
by_type = statement['transactions'].group_by { |t| t['type'] }
# Calculate net change
net_change = statement['balances']['closingBalance'] -
statement['balances']['openingBalance']
puts "Large transactions: #{large_transactions.count}"
puts "Net change: $#{net_change}"SQL (PostgreSQL)
Import JSON to database for querying
-- Create table for transactions
CREATE TABLE transactions (
id VARCHAR(50) PRIMARY KEY,
date DATE,
description TEXT,
amount DECIMAL(10,2),
type VARCHAR(10),
balance DECIMAL(10,2),
category VARCHAR(50)
);
-- Import from JSON (using jsonb column)
INSERT INTO transactions
SELECT
t->>'id',
(t->>'date')::DATE,
t->>'description',
(t->>'amount')::DECIMAL,
t->>'type',
(t->>'balance')::DECIMAL,
t->>'category'
FROM jsonb_array_elements(
(SELECT jsonb_build_object('transactions', content)
FROM statement_json)
-> 'transactions'
) t;Popular Libraries
- JavaScript: Native JSON.parse(), lodash for utilities
- Python: json module, pandas for analysis
- Ruby: Native JSON module, Oj gem for performance
- PHP: json_decode(), league/json-guard for validation
- Java: Gson, Jackson, org.json
- Go: encoding/json package
Testing Tools
- JSONLint: Validate JSON syntax online
- Postman: Test API responses and webhooks
- jq: Command-line JSON processor (Unix/Linux)
- JSON Schema: Define and validate structure
- Ajv: Fast JSON schema validator
Should I store the amount field as a float?
Not if you plan to add the numbers up. Binary floating point cannot represent most cent values exactly, so summing a few thousand transactions can leave you a fraction of a cent off the closing balance. Convert each amount to integer cents on ingest, or use a decimal type (decimal.Decimal in Python, NUMERIC in Postgres), and only format back to dollars for display.
Why do my transaction dates show up one day early in JavaScript?
Passing a date-only string such as 2026-03-01 to new Date() treats it as midnight UTC. Anywhere west of Greenwich, that renders as the evening of the previous day. Bank statement dates have no time component, so keep them as plain strings for sorting and grouping, or parse the year, month, and day yourself and build a local date.
How can my code tell whether a converted file is missing transactions?
Schema validation only proves the shape is right. To check completeness, add up every transaction amount and confirm that the opening balance plus that total equals the closing balance in the balances object, working in cents. If it does not match, reject the file into a review queue instead of loading it, and log the size of the gap so someone can compare it against the PDF.
Frequently Asked Questions
Start Building with JSON Bank Statement Data
Convert bank statement PDFs to structured JSON format for your fintech application, API integration, or data processing pipeline. Developer-friendly format, production-ready quality.
Convert PDF to JSONStructured data β’ CSV, Excel, and JSON β’ API access on Enterprise (contact us)