ACCOUNTRIX AI

TallyPrime XML Integration — A Technical Guide for CA Software Developers

The TallyPrime XML/HTTP gateway: port 9000 setup, ENVELOPE request structure, exporting a Trial Balance, and the encoding and date gotchas.

How the gateway works

TallyPrime exposes a local HTTP gateway. When you enable it (in the company's connectivity settings, with Tally acting as a server), Tally listens on port 9000 and accepts XML requests over plain HTTP. There is no REST, no OAuth and no JSON — you POST a well-formed XML envelope and Tally streams back an XML (or SDF) response. Everything is local to the machine running Tally, which is why a desktop connector, rather than a cloud call, is the right architecture.

The request envelope

Every request is an ENVELOPE with a HEADER declaring the request type and a BODY describing what you want. To export a Trial Balance for a date range, the request looks like this:

<ENVELOPE>
  <HEADER>
    <TALLYREQUEST>Export Data</TALLYREQUEST>
  </HEADER>
  <BODY>
    <EXPORTDATA>
      <REQUESTDESC>
        <REPORTNAME>Trial Balance</REPORTNAME>
        <STATICVARIABLES>
          <SVCURRENTCOMPANY>Acme Traders</SVCURRENTCOMPANY>
          <SVFROMDATE>20250401</SVFROMDATE>
          <SVTODATE>20260331</SVTODATE>
          <SVEXPORTFORMAT>$SysName:XML</SVEXPORTFORMAT>
        </STATICVARIABLES>
      </REQUESTDESC>
    </EXPORTDATA>
  </BODY>
</ENVELOPE>

The SVCURRENTCOMPANY value must match the open company name exactly, character for character. A trailing space or a different case returns an empty result rather than an error, which is a common source of "it returns nothing" support tickets.

Parsing the response

The response mirrors the report structure: a collection of ledgers, each with its name and closing balance. Balances come back as numbers whose sign encodes Dr/Cr — a debit closing balance is positive, a credit is negative (or vice versa depending on the report), so you must interpret the sign against the head, not assume all balances are positive. Amounts are unformatted decimals; there are no thousands separators in the raw data, which is a relief.

The gotchas that cost a day each

  • Encoding. Tally emits some control characters and entity-like markers (for example &#4;) in ledger names. Strip or sanitise these before you store the names, or your downstream XML/JSON will choke.
  • Dates. Static variables expect YYYYMMDD with no separators. Send 2025-04-01 and you get silent garbage, not an exception.
  • Company switching. If multiple companies are open, the request acts on the one named in SVCURRENTCOMPANY; if that name is wrong, Tally falls back to the active company and you get the wrong client's data without any warning.
  • Amount signs. Opening, debit, credit and closing each carry their own sign convention per report. Reconcile a known ledger by hand the first time you integrate a new report, rather than trusting the sign blindly.
  • Custom data. Anything beyond the built-in reports requires a TDL collection defined in the request; the gateway will only return fields the report actually exposes.

Putting it together

A robust connector enables the gateway, confirms the exact company name, sends the export request with correctly formatted dates, sanitises the returned names, and normalises the amount signs against each head before handing clean data to the statement engine. Do that, and a year of ledgers crosses from Tally into a compliant trial balance in a couple of seconds — offline, on the client's own machine, with no financial amounts ever leaving the premises.