ml-connector
TallyPrimeAvalara

TallyPrime and Avalara integration

This connection links TallyPrime, a desktop accounting and ERP application, to Avalara AvaTax, a cloud sales and use tax calculation service. ml-connector reads sales and purchase vouchers from TallyPrime and submits them to Avalara as transactions, so each line gets jurisdiction-correct tax based on ship-from and ship-to addresses. The calculated tax amount comes back and is written onto the matching TallyPrime voucher. Because TallyPrime runs a local HTTP server and Avalara is a hosted REST API, the integration bridges an on-premise envelope interface to a cloud tax engine and keeps document codes aligned so the two systems agree on every transaction.

How TallyPrime works

TallyPrime does not offer a hosted cloud API. It runs a local HTTP server on port 9000 that accepts XML or JSON envelopes over HTTP POST, where the TALLYREQUEST field selects Export Data (read) or Import Data (write). Because that port is only reachable on the local machine or LAN, a connector reaches it through an on-premise local agent that forwards envelopes to localhost and relays responses. Accounts such as customers and suppliers are Ledgers, while sales and purchase bills are vouchers identified by type and voucher number. There is no transport-level API key or OAuth; security is expected from network controls, and the company name is passed in the SVCURRENTCOMPANY header. TallyPrime never pushes events, so change detection is done by polling the Day Book with SVFROMDATE and SVTODATE date filters; there is no native pagination, so requests are narrowed by date window.

How Avalara works

Avalara AvaTax exposes a REST v2 API as JSON over HTTPS at https://rest.avatax.com/api/v2, with a separate sandbox at https://sandbox-rest.avatax.com/api/v2. Authentication is HTTP Basic using a numeric account ID and a per-account license key, Base64-encoded on every request; the license key survives user password changes, which suits server-to-server connectors. The central object is the Transaction, created with POST /api/v2/transactions and typed as SalesInvoice, PurchaseInvoice, SalesOrder, PurchaseOrder, or ReturnInvoice. Calls are synchronous and return the full calculated tax inline. AvaTax has no vendor, purchase order, GL account, or payment objects of its own; those values are passed as string references such as customerCode, purchaseOrderNo, and referenceCode. List endpoints use OData-style $top, $skip, and $filter with a 1000-record page cap, and AvaTax does not push webhooks, so reconciliation is done by polling ListTransactionsByCompany.

What moves between them

The primary direction is from TallyPrime to Avalara. ml-connector polls the TallyPrime Day Book on a schedule, picks up new sales and purchase vouchers, and submits each one to Avalara as a SalesInvoice or PurchaseInvoice transaction with its line items, amounts, tax codes, and ship-from and ship-to addresses. Avalara returns the calculated tax synchronously in the same call. ml-connector then writes that tax result back into TallyPrime against the originating voucher, using the Alter action and the voucher tag so it updates the record rather than creating a duplicate. Customer ledgers and stock items can be pushed to Avalara as customer codes and items so tax determination has the references it needs. A polling interval of five to fifteen minutes fits most accounting workflows; the connector tracks the last-seen voucher state because TallyPrime offers no change stream.

How ml-connector handles it

The auth bridge has two sides. On the TallyPrime side, ml-connector calls a customer-installed local agent that proxies XML or JSON envelopes to http://localhost:9000, since port 9000 is not reachable from the cloud and ships disabled until the customer enables the HTTP server. On the Avalara side, ml-connector sends Base64 HTTP Basic credentials built from the account ID and license key on every REST call. Mapping is convention-based: TallyPrime ledger names become Avalara customer codes, stock items map to items with Avalara tax codes, and each voucher number is reused as the Avalara document code. That last detail is the core idempotency safeguard, because Avalara treats the document code as its dedup key; ml-connector uses CreateOrAdjustTransaction so a retried, uncommitted voucher updates in place instead of erroring. Real edge cases are handled directly. TallyPrime requires the YYYYMMDD date format and returns errors as XML text rather than codes, so responses are parsed for LINEERROR and IMPORTRESULT blocks. TallyPrime is single-user, so calls to one instance stay sequential to avoid lag. Avalara returns 429 without a documented Retry-After, so the connector backs off with exponential delay and jitter. Once an Avalara transaction is committed its code is reserved, so corrections go through void and re-create or adjust rather than overwrite, and invalid addresses are pre-checked with /addresses/resolve before submission.

A real-world example

A mid-sized distributor with about 120 staff runs its books in TallyPrime on-premise but sells into several US states and faces growing use-tax exposure on interstate purchases. Their accounting team had been keying tax rates by hand from spreadsheets, which produced inconsistent rates across jurisdictions and slowed month-end close. After connecting TallyPrime to Avalara, every sales and purchase voucher is sent to AvaTax for an address-accurate tax figure that is written straight back onto the voucher. Manual rate lookups disappear, the books match what Avalara has on file for return filing, and staff stop reconciling tax differences by hand.

What you can do

  • Send TallyPrime sales and purchase vouchers to Avalara for address-accurate tax calculation.
  • Write the calculated tax amount back onto the originating TallyPrime voucher automatically.
  • Reach an on-premise TallyPrime instance from the cloud through a local agent on port 9000.
  • Reuse each voucher number as the Avalara document code so retries never double-post.
  • Pre-validate ship-to addresses with Avalara before submitting a transaction for tax.

Questions

Does TallyPrime need to be exposed to the internet for this to work?
No. TallyPrime's HTTP server on port 9000 is only reachable from the local machine or LAN, and that port should never face the public internet. ml-connector reaches it through an on-premise local agent that forwards XML or JSON envelopes to localhost and relays the responses. The agent authenticates to ml-connector, so the Tally port stays behind the customer's firewall.
How does the integration avoid creating duplicate tax records?
Each TallyPrime voucher number is reused as the document code on the Avalara transaction, and Avalara treats that code as its deduplication key. ml-connector uses the CreateOrAdjustTransaction call, so re-sending an uncommitted voucher updates it in place rather than creating a second one. Once a transaction is committed its code is reserved, so corrections go through void and re-create or adjust instead of overwriting.
Can Avalara store our vendors, purchase orders, or GL accounts?
No. AvaTax is a tax calculation service and has no native objects for vendors, purchase orders, GL accounts, or payments. Those records stay in TallyPrime, and the integration passes the relevant values to Avalara as string references such as customerCode, purchaseOrderNo, and referenceCode on the transaction. AvaTax uses them to determine tax and for reporting, not as a master data store.

Related integrations

Connect TallyPrime and Avalara

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started