cas-pdf-parser
v0.1.3
Published
Parse Indian Consolidated Account Statement (CAS) PDFs — CAMS, KFintech, NSDL, CDSL
Maintainers
Readme
cas-pdf-parser
Parse Indian Consolidated Account Statement (CAS) PDFs in Node.js and the browser.
Supports CAMS, KFintech, NSDL, and CDSL statements — detailed and summary formats.
npm install cas-pdf-parserQuick Start
import { readCasPdf } from 'cas-pdf-parser';
const data = await readCasPdf('/path/to/cas.pdf', 'YOURPASSWORD');
console.log(data.investor_info.name);
console.log(data.file_type); // "CAMS" | "KFINTECH" | "NSDL" | "CDSL"API
readCasPdf(input, password, options?)
| Parameter | Type | Description |
|---|---|---|
| input | string \| Buffer \| Uint8Array \| File | File path (Node.js), Buffer, Uint8Array, or browser File |
| password | string | PDF password — usually PAN number or registered email |
| options.workerSrc | string | Path to pdfjs worker (required in browsers) |
| options.output | 'object' \| 'json' | Return type. Default: 'object' (Decimal values). 'json' returns plain strings |
Returns Promise<CASData> for CAMS/KFintech, or Promise<NSDLCASData> for NSDL/CDSL.
Usage Examples
Node.js — file path
import { readCasPdf } from 'cas-pdf-parser';
const data = await readCasPdf('./statement.pdf', 'ABCDE1234F');
if (data.file_type === 'CAMS' || data.file_type === 'KFINTECH') {
for (const folio of data.folios) {
console.log(folio.amc, folio.folio);
for (const scheme of folio.schemes) {
console.log(scheme.scheme, scheme.valuation.value.toString());
}
}
}Node.js — Buffer
import { readFile } from 'fs/promises';
import { readCasPdf } from 'cas-pdf-parser';
const buffer = await readFile('./statement.pdf');
const data = await readCasPdf(buffer, 'ABCDE1234F');Node.js — JSON output (Decimal as string)
const data = await readCasPdf('./statement.pdf', 'ABCDE1234F', { output: 'json' });
// data.folios[0].schemes[0].valuation.value is now a plain string, safe for JSON.stringify
console.log(JSON.stringify(data, null, 2));Browser — File input
import { readCasPdf } from 'cas-pdf-parser';
import { GlobalWorkerOptions } from 'pdfjs-dist';
// Set worker once (Vite example)
import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url';
GlobalWorkerOptions.workerSrc = workerSrc;
async function onFileSelected(file: File, password: string) {
const data = await readCasPdf(file, password);
console.log(data);
}Response Shape
CAMS / KFintech — CASData
{
file_type: "CAMS", // "CAMS" | "KFINTECH"
cas_type: "DETAILED", // "DETAILED" | "SUMMARY"
statement_period: {
from: "01-Apr-2024",
to: "30-Jun-2024"
},
investor_info: {
name: "JOHN DOE",
email: "[email protected]",
address: "123 Main St, Mumbai",
mobile: "9999999999"
},
folios: [
{
folio: "1234567/89",
amc: "HDFC Mutual Fund",
PAN: "ABCDE1234F",
KYC: "OK",
PANKYC: "OK",
holderName: "JOHN DOE",
schemes: [
{
scheme: "HDFC Mid Cap Opportunities Fund - Growth",
isin: "INF179K01VQ1",
amfi: "118989",
rta: "CAMS",
rta_code: "HDF",
advisor: null,
type: null,
nominees: ["JANE DOE"],
open: Decimal("100.000"), // units at period start
close: Decimal("150.000"), // units at period end (from PDF)
close_calculated: Decimal("150.000"), // units computed from transactions
valuation: {
date: "2024-06-30",
nav: Decimal("87.45"),
value: Decimal("13117.50"),
cost: Decimal("10000.00")
},
transactions: [
{
date: "2024-04-10",
description: "SIP Purchase",
amount: Decimal("5000.00"),
units: Decimal("57.178"),
nav: Decimal("87.45"),
balance: Decimal("150.000"),
type: "PURCHASE_SIP",
dividend_rate: null,
gift_folio: null
}
]
}
]
}
],
parse_warnings: []
}NSDL / CDSL — NSDLCASData
{
file_type: "NSDL", // "NSDL" | "CDSL"
statement_period: {
from: "01-Apr-2024",
to: "30-Jun-2024"
},
investor_info: {
name: "JOHN DOE",
email: "[email protected]",
address: "123 Main St",
mobile: "9999999999"
},
accounts: [
{
name: "IN123456789012",
type: "DEMAT",
dp_id: "IN123456",
client_id: "789012",
folios: 2,
balance: Decimal("150000.00"),
owners: [
{ name: "JOHN DOE", PAN: "ABCDE1234F" }
],
equities: [
{
isin: "INE002A01018",
name: "Reliance Industries Limited",
symbol: "RELIANCE",
exchange: "NSE",
num_shares: Decimal("10"),
price: Decimal("2950.00"),
value: Decimal("29500.00")
}
],
mutual_funds: [
{
isin: "INF179K01VQ1",
name: "HDFC Mid Cap Opportunities Fund",
amfi: "118989",
type: null,
balance: Decimal("150.000"),
nav: Decimal("87.45"),
value: Decimal("13117.50"),
avg_cost: Decimal("66.67"),
total_cost: Decimal("10000.00"),
ucc: null,
folio: "1234567/89",
pnl: Decimal("3117.50"),
return: Decimal("31.18")
}
],
bonds: [
{
isin: "INE001A07NX1",
name: "SBI Bond Series",
num_bonds: Decimal("5"),
value: Decimal("50000.00"),
face_value: Decimal("10000.00"),
coupon_rate: Decimal("7.50"),
coupon_frequency: "Annual",
maturity_date: "2028-03-31",
market_price: Decimal("10200.00")
}
]
}
],
nps: {
pran: "110012345678",
nps_sp: "SBI Pension Funds",
value: Decimal("250000.00"),
schemes: [
{
scheme: "SBI Pension Fund - Scheme E - Tier I",
fund_manager: "SBI Pension Funds",
tier: "I",
asset_class: "E",
units: Decimal("1500.000"),
nav: Decimal("45.20"),
value: Decimal("67800.00")
}
]
},
parse_warnings: []
}Transaction Types
| Value | Description |
|---|---|
| PURCHASE | Lump sum purchase |
| PURCHASE_SIP | SIP / recurring purchase |
| REDEMPTION | Full or partial redemption |
| DIVIDEND_PAYOUT | Dividend paid out to bank |
| DIVIDEND_REINVEST | Dividend reinvested as units |
| SWITCH_IN | Switch in from another scheme |
| SWITCH_IN_MERGER | Switch in due to scheme merger |
| SWITCH_OUT | Switch out to another scheme |
| SWITCH_OUT_MERGER | Switch out due to scheme merger |
| STT_TAX | Securities Transaction Tax |
| STAMP_DUTY_TAX | Stamp duty |
| TDS_TAX | TDS deduction |
| SEGREGATION | Side-pocketed units |
| GIFT_IN | Units received as gift |
| GIFT_OUT | Units gifted out |
| REVERSAL | Reversed transaction |
| MISC | Other / unclassified |
Decimal Values
All financial values are Decimal instances from decimal.js for exact arithmetic. Convert to string or number as needed:
scheme.valuation.value.toString() // "13117.50"
scheme.valuation.value.toNumber() // 13117.5
scheme.valuation.value.toFixed(2) // "13117.50"Use output: 'json' to get plain strings instead:
const data = await readCasPdf(file, password, { output: 'json' });
// All Decimal fields are now plain strings — safe to JSON.stringify directlyError Handling
import { readCasPdf, IncorrectPasswordError, UnsupportedFormatError } from 'cas-pdf-parser';
try {
const data = await readCasPdf(file, password);
} catch (err) {
if (err instanceof IncorrectPasswordError) {
console.error('Wrong password');
} else if (err instanceof UnsupportedFormatError) {
console.error('Not a supported CAS PDF');
} else {
console.error('Parse failed:', err.message);
}
}ISIN Resolver (optional)
Plug in your own ISIN database to enrich equity symbols:
import { setIsinResolver, setEquitySymbolResolver } from 'cas-pdf-parser';
setIsinResolver(async (isin) => {
const row = await db.query('SELECT * FROM isins WHERE isin = ?', [isin]);
return row ? { isin: row.isin, name: row.name, type: row.type } : null;
});
setEquitySymbolResolver(async (isin) => {
return myApi.getSymbol(isin); // returns "RELIANCE" | null
});Supported Formats
| Source | Format | Notes | |---|---|---| | CAMS | Detailed, Summary | MF transactions + valuations | | KFintech | Detailed, Summary | MF transactions + valuations | | NSDL | Demat CAS | Equities, MF, Bonds, NPS | | CDSL | Demat CAS | Equities, MF, Bonds, ETF routed to MF |
License
MIT
