Federal Bank Statement Parser: Extract JSON with AI
Parse any Federal Bank statement — savings, NRI, or current account — into structured JSON with AI. TypeScript guide for Indian fintech developers.
Federal Bank is one of India's oldest and most respected private sector banks, founded in 1931 in Kerala. With over 12 million customers and one of the largest NRI banking franchises among Indian private banks, Federal Bank statements appear frequently in lending pipelines targeting South Indian borrowers and the diaspora. Yet most developers encounter Federal Bank PDFs for the first time when a loan applicant uploads one — and standard OCR tools immediately struggle.
This guide shows you how to extract structured JSON from any Federal Bank statement using Lekha — a financial document intelligence API built for Indian fintech developers — with TypeScript code you can drop into your project today.
Why Federal Bank Statements Are Hard to Parse
Federal Bank generates statements through multiple channels, each with distinct layouts and quirks.
| Statement type | Source | Common challenges | | ----------------------- | ----------------------- | -------------------------------------------- | | Savings / Current | FedNet internet banking | Multi-page, variable font size | | NRI accounts (NRE/NRO) | FedMobile / NRI portal | Multi-currency rows, SWIFT reference codes | | Senior Citizen accounts | Branch-printed | Scanned, larger fonts, irregular spacing | | Current account | Business banking portal | Long narrations, cheque serial numbers | | Salary account | HR partner portal | Employer-branded header over the bank layout |
Beyond format variation, Federal Bank statements routinely include:
SWIFT/OUR/HSBC LONDON/GBP12500 that break simple regex parsers.Template-based parsers break whenever Federal Bank updates its layout. Vision AI reads the document semantically — understanding that "NEFT CR" followed by an amount is a credit regardless of column position.
What Lekha Returns for Federal Bank Statements
Lekha normalises Federal Bank statements into a consistent JSON schema regardless of account type or source format:
{
"document_type": "bank_statement",
"bank": "Federal Bank",
"account": {
"holder_name": "Thomas Varghese",
"account_number": "XXXXXXXX7823",
"account_type": "Savings",
"ifsc": "FDRL0001234",
"branch": "Thrissur Main Branch, Kerala"
},
"period": {
"from": "2026-04-01",
"to": "2026-06-30"
},
"summary": {
"opening_balance": 38200.0,
"closing_balance": 95450.75,
"total_credits": 312800.0,
"total_debits": 255549.25
},
"transactions": [
{
"date": "2026-04-05",
"narration": "NEFT CR-INFOSYS BPO/SALARY APR26/FDRL0001234",
"reference": "N042600000123",
"debit": null,
"credit": 72000.0,
"balance": 110200.0,
"category": "salary",
"channel": "NEFT"
},
{
"date": "2026-04-12",
"narration": "UPI/P2P/thomas@okaxis/Food/1234567890",
"reference": "UPI2604001234",
"debit": 850.0,
"credit": null,
"balance": 109350.0,
"category": "food",
"channel": "UPI"
}
]
}
Every amount is a number — never a string like "₹72,000". Dates are ISO 8601. The category field is Lekha's automatic transaction classification (salary, UPI, EMI, tax, investment), which eliminates a downstream categorisation step.
Quick Start: Extract a Federal Bank Statement
Install the Lekha SDK and extract your first statement in three lines:
import { LekhaClient } from "@lekhadev/sdk";
import { readFileSync } from "fs";
const client = new LekhaClient({ apiKey: process.env.LEKHA_API_KEY });
const result = await client.extract({
document: readFileSync("federal-bank-statement.pdf"),
documentType: "bank_statement",
});
if (result.success) {
console.log(result.data.summary.total_credits); // 312800
console.log(result.data.transactions.length); // transaction count
}
documentType is optional — Lekha's classifier detects it automatically. Providing it explicitly is recommended when you know what you're processing: it speeds up extraction and lets Lekha apply bank-specific parsing heuristics immediately.
Try it with a real statement at lekhadev.com/playground.
Handling NRI Account Statements
Federal Bank is particularly popular for NRI banking. NRE and NRO account statements carry additional fields for inward remittances — credits that typically originate as SWIFT transfers from abroad and count as income in lending assessments.
const nriResult = await client.extract({
document: readFileSync("federal-nre-statement.pdf"),
documentType: "bank_statement",
});
if (nriResult.success) {
const { transactions } = nriResult.data;
// Identify inward remittances by channel or narration keyword
const remittances = transactions.filter(
(txn) =>
txn.credit !== null &&
(txn.channel === "SWIFT" ||
txn.narration.toLowerCase().includes("inward") ||
txn.narration.toLowerCase().includes("fcnr")),
);
const totalRemitted = remittances.reduce(
(sum, txn) => sum + (txn.credit ?? 0),
0,
);
console.log(${remittances.length} inward remittances);
console.log(Total: ₹${totalRemitted.toLocaleString("en-IN")});
}
NRI income verification in Indian lending typically requires at least 6 months of NRE/NRO statements. Lekha's period field tells you exactly what date range the statement covers so you can prompt the user to upload additional months if needed.
Building a Loan Eligibility Pipeline
Here is a complete pipeline that processes a Federal Bank statement and computes average monthly income for a lending decision:
import { LekhaClient } from "@lekhadev/sdk";
const client = new LekhaClient({ apiKey: process.env.LEKHA_API_KEY });
interface IncomeReport {
averageMonthlyCredit: number;
salaryCreditsFound: number;
monthsCovered: number;
isEligible: boolean;
flags: string[];
}
async function analyzeIncome(
statementBuffer: Buffer,
minimumMonthlyIncome: number,
): Promise {
const result = await client.extract({
document: statementBuffer,
documentType: "bank_statement",
});
if (!result.success) {
throw new Error(result.error.message);
}
const { transactions, period } = result.data;
const flags: string[] = [];
// Identify salary credits
const salaryTxns = transactions.filter(
(txn) =>
txn.credit !== null &&
(txn.category === "salary" ||
txn.narration.toLowerCase().includes("salary") ||
txn.narration.toLowerCase().includes("sal ")),
);
// Calculate months spanned by the statement
const fromDate = new Date(period.from);
const toDate = new Date(period.to);
const monthsCovered =
(toDate.getFullYear() - fromDate.getFullYear()) * 12 +
(toDate.getMonth() - fromDate.getMonth()) +
1;
const totalCredits = transactions
.filter((txn) => txn.credit !== null)
.reduce((sum, txn) => sum + (txn.credit ?? 0), 0);
const averageMonthlyCredit = Math.round(totalCredits / monthsCovered);
if (salaryTxns.length === 0) {
flags.push("No salary credits identified — income source unclear");
}
if (monthsCovered < 3) {
flags.push(
Statement covers only ${monthsCovered} month(s) — 3 minimum recommended,
);
}
if (averageMonthlyCredit < minimumMonthlyIncome) {
flags.push(
Average monthly credit ₹${averageMonthlyCredit.toLocaleString("en-IN")} is below the ₹${minimumMonthlyIncome.toLocaleString("en-IN")} threshold,
);
}
return {
averageMonthlyCredit,
salaryCreditsFound: salaryTxns.length,
monthsCovered,
isEligible: flags.length === 0,
flags,
};
}
// Usage
const report = await analyzeIncome(
readFileSync("federal-bank-q1-2026.pdf"),
50000, // ₹50,000 minimum monthly income required
);
console.log(report.isEligible); // true
console.log(report.averageMonthlyCredit); // 72000
console.log(report.flags); // []
This runs end-to-end in under three seconds. The extraction step handles the PDF complexity; your business logic stays clean and bank-format-agnostic.
Common Edge Cases
Password-protected PDFs — Federal Bank's FedNet portal allows customers to password-protect downloaded statements. Pass the password directly to Lekha and it decrypts before extraction:const result = await client.extract({
document: buffer,
documentType: "bank_statement",
password: "THOMAS@1990", // customer-set password
});
Scanned branch statements — older Federal Bank statements issued at branches are sometimes printed and scanned. Pass the scan as a PNG, JPG, or image-based PDF directly. Lekha's vision model reads them the same way — no separate code path needed.
Partial-period statements — Federal Bank occasionally issues statements that don't align to a full calendar month (e.g., when an account is opened mid-month or when a customer requests a custom date range). The period.from and period.to in the output reflect the actual transaction date range, so your monthsCovered calculation stays accurate without any special handling.
Statements with zero transactions — if a dormant account produces an empty statement, transactions is an empty array and summary.total_credits is 0. Your pipeline should check for this and prompt the user accordingly rather than proceeding with a zero-income assessment.
FAQ
Does Lekha support all Federal Bank account types?Yes. Savings, current, NRE, NRO, salary, and senior citizen account statements all map to the same output schema. NRI-specific fields (transaction currency, SWIFT reference) are populated when present and null otherwise, so your code doesn't need to branch per account type.
Lekha's vision model reads the document visually rather than relying on PDF text extraction. Malayalam characters in narration fields are either transliterated (when the meaning is standard banking terminology) or preserved as Unicode. The category field correctly identifies salary, EMI, and UPI transactions even when the narration contains Malayalam text.
Extract each statement with a separate client.extract() call and merge the results in your application layer. Both calls return the same schema. To calculate total available income, sum salary credits and inward remittances across both accounts before passing the aggregate to your eligibility model.
Yes. Lekha supports Federal Bank alongside South Indian Bank, Karnataka Bank, Karur Vysya Bank, and Dhanlaxmi Bank — plus all major national banks (HDFC, ICICI, SBI, Axis, Kotak, PNB, and others). A single integration handles every bank your customers use. See the full supported list at lekhadev.com/docs.
Ready to add Federal Bank statement parsing to your lending or KYC pipeline? Sign up at lekhadev.com — 100 free extractions, no credit card required. The API is live in under five minutes.