tally-to-xml-tdl
Pull clean, structured JSON from Tally Prime — no plugins, no configuration overhead, just Node.js.
Tally exposes a local HTTP port. This library speaks to it directly via TDL-based XML requests and returns plain JavaScript objects ready to query, inspect, and use.
How it works #
:9000Three operations happen seamlessly inside every function call:
- Build — a shared
body.xmltemplate is populated with your active company name, date filters, and TDL collection message. - Send — the formulated XML request is POSTed to Tally's local HTTP listener (
http://localhost:9000by default). - Parse — Tally's raw XML response envelope is converted into a standard JavaScript object graph.
You receive the raw envelope, exactly as Tally produced it. There is no lossy data manipulation, no stripping of attributes, and no hidden transformation.
Install #
npm install tally-to-xml-tdl
Gateway of Tally → F12 → Advanced Configuration → Enable HTTP: Yes (Port: 9000)
Quick start #
import { company, masters, vouchers } from "tally-to-xml-tdl";
// 1. List all open companies in Tally
const companies = await company();
// 2. Get stock items for an active company
const stock = await masters.get("My Company", "stockItems");
// 3. Get purchase vouchers for a specified date range
const purchases = await vouchers.purchases.period(
"My Company",
"1-Apr-2026",
"30-Apr-2026"
);
API Reference #
company()
Lists all companies currently opened in the running Tally Prime instance.
import { company } from "tally-to-xml-tdl";
const result = await company();
// result.ENVELOPE.BODY.DATA.COLLECTION.COMPANY → [ { NAME: "..." }, ... ]
masters.get(company, queryId)
Fetches master catalogs (stock items, ledgers, units, groups) for a given company.
import { masters } from "tally-to-xml-tdl";
const result = await masters.get("My Company", "stockItems");
Supported queryId parameters:
| queryId | Returned Data Structure |
|---|---|
| uom | Units of Measure definitions |
| stockItems | Stock item names list |
| stockItemsWithBaseUnits | Stock items paired with their base units |
| ledgerNames | Ledger account names |
| ledgerNamesWithDetails | Ledgers with GST registration type and GSTIN |
| ledgerNamesMoreDetails | Ledgers with extended GST registration details table |
| stockGroups | Stock group names hierarchy |
| stockGroupsAndParent | Stock groups along with parent group relationships |
vouchers.purchases.period(company, fromDate, toDate)
Fetches purchase vouchers within a date window including inventory details.
import { vouchers } from "tally-to-xml-tdl";
const result = await vouchers.purchases.period(
"My Company",
"1-Apr-2026",
"30-Apr-2026"
);
const voucherList = result.ENVELOPE.BODY.DATA.COLLECTION.VOUCHER;
console.log(voucherList.length); // e.g. 46
vouchers.purchases.all(company)
Fetches all purchase vouchers across all available financial dates.
const result = await vouchers.purchases.all("My Company");
vouchers.sales.get(company, fromDate, toDate, "period")
Fetches sales vouchers for a date range.
const result = await vouchers.sales.get(
"My Company",
"1-Apr-2026",
"30-Apr-2026",
"period"
);
Response shape #
Every function call returns the raw Tally XML envelope directly translated into JSON:
{
"ENVELOPE": {
"HEADER": { /* Tally export metadata */ },
"BODY": {
"DATA": {
"COLLECTION": {
"VOUCHER": [
{
"DATE": "20260401",
"GUID": "...",
"VOUCHERTYPENAME": "Purchase"
}
]
// Or STOCKITEM, LEDGER, UNIT depending on query
}
}
}
}
}
To extract the actual record array in your application:
const records = result.ENVELOPE.BODY.DATA.COLLECTION.VOUCHER;
Date format #
Tally Prime requires dates formatted as day, month abbreviation, and year. For example:
"D-MMM-YYYY" (e.g. "1-Apr-2026", "30-Apr-2026")
Requirements #
| Requirement | Specification |
|---|---|
| Node.js | >=18 (leverages native global fetch) |
| Tally Prime | Any modern release with HTTP port export enabled |
| HTTP Listener | Port 9000 active by default in Tally |
| Module System | Pure ECMAScript Module ("type": "module") |