ml-connector
Sage IntacctTaxJar

Sage Intacct and TaxJar integration

Sage Intacct handles accounting and financial close. TaxJar handles sales tax calculation and state reporting. Connecting the two means your sales transactions flow from Sage Intacct to TaxJar for real-time tax calculation, and the resulting tax liability journals post back into Sage Intacct automatically, allocated to the correct tax GL accounts and dimensions. Your month-end close no longer requires manual tax provision entries or reconciliation between the two systems.

How Sage Intacct works

Sage Intacct exposes vendors, AP bills, AP payments, GL accounts, and dimensions through a single XML gateway endpoint at https://api.intacct.com/ia/xml/xmlgw.phtml. Authentication is session-based: an initial getAPISession call exchanges senderId, senderPassword, companyId, userId, and userPassword for a sessionid that is cached for 50 minutes. HTTP 200 responses may contain application-level errors inside the XML body, so every response must be parsed for errormessage tags. Sage Intacct does not push webhooks; all data flows are scheduled polls or manual runs. The XML gateway requires all operations to serialize through one POST connection.

How TaxJar works

TaxJar exposes tax calculation, transaction reporting, nexus regions, and tax rates through REST JSON endpoints at https://api.taxjar.com/v2/. Authentication is token-based: merchants generate an API token from the TaxJar app and ml-connector presents it via the Authorization header. TaxJar does not support OAuth2 and does not publish webhooks or push events to external endpoints, so all data flows are poll-based or merchant-initiated. Sandbox tokens are available on Professional plans and higher. Transaction endpoint calls do not count against the monthly API threshold.

What moves between them

Sales and refund transactions are read from Sage Intacct via polling. Each transaction is sent to TaxJar to calculate the exact sales tax liability based on nexus and jurisdiction. The resulting tax provision GL entry is constructed in Sage Intacct's GL account and dimension format and posted back into the general ledger. Tax provisions are aligned to the correct GL accounts so your balance sheet reflects the accurate tax liability. The flow runs on a schedule you configure; TaxJar's sandbox can validate request and response format without persisting data.

How ml-connector handles it

ml-connector caches Sage Intacct session tokens for the full 50-minute lifetime and refreshes them automatically on the next call if expiry is reached. It accepts the Sage Intacct credentials (senderId, companyId, userId, userPassword) encrypted and exchanges them for a sessionid on first use. For TaxJar, it stores the API token encrypted and presents it via the Authorization header on every request. Transactions are read from Sage Intacct, each transaction is posted to TaxJar's /v2/taxes endpoint to calculate the liability, and the resulting GL entry is constructed with the correct GL account and dimension references before posting back into Sage Intacct via the XML gateway. Forbidden XML control characters must be stripped before escaping entity references. The integration handles HTTP 200 responses that contain application-level errors by parsing the XML body for errormessage tags. If a transaction is retried, Sage Intacct's uniqueid flag on the control block deduplicates the operation on the server side. TaxJar transactions are idempotent: if a POST returns 422 (already exists), the call falls back to PUT; if PUT returns 404, it falls back to POST.

A real-world example

A mid-sized e-commerce retailer runs Sage Intacct for accounting and financial close, and operates across multiple states and nexus jurisdictions. Before the integration, the finance team exported sales transactions from their e-commerce system weekly, manually entered them into Sage Intacct, then ran a separate tax report in TaxJar to calculate state sales tax liability, often discovering mid-month that the provision amount in Sage Intacct did not match TaxJar's calculated liability. Month-end close included reconciling the two systems and manually adjusting the GL entries. With Sage Intacct and TaxJar connected, sales transactions flow from Sage Intacct to TaxJar on a daily schedule, tax provisions are calculated automatically and posted to the GL with the correct account and state dimension, and the close process begins with both systems already in agreement. The manual reconciliation and adjustment steps are gone.

What you can do

  • Read sales and refund transactions from Sage Intacct and calculate exact sales tax liability in TaxJar based on nexus and jurisdiction.
  • Post tax provision GL entries back into Sage Intacct's general ledger, allocated to the correct tax GL accounts and dimensions.
  • Manage Sage Intacct session token caching and automatic refresh, and TaxJar API token storage and presentation.
  • Validate GL accounts and dimensions before posting tax provisions, and handle HTTP 200 responses that contain application-level errors inside the XML body.
  • Handle retried transactions with Sage Intacct's uniqueid server-side deduplication and TaxJar's POST/PUT idempotency workaround.

Questions

Which direction does data move between Sage Intacct and TaxJar?
Sales and refund transactions are read from Sage Intacct and sent to TaxJar for tax calculation. The resulting tax provision GL entry is posted back into Sage Intacct's general ledger. Reference data such as GL accounts and dimensions are used from Sage Intacct to structure the provision posting correctly.
How does the integration handle Sage Intacct's session token and TaxJar's API token?
ml-connector caches Sage Intacct's sessionid for the full 50-minute lifetime and automatically refreshes it on the next call if expiry is reached. TaxJar's API token is stored encrypted and presented via the Authorization header on every request. Both credentials are stored encrypted at rest.
What happens if a transaction is already reported to both systems?
Sage Intacct uses a uniqueid flag on the control block to deduplicate retried operations server-side. TaxJar handles idempotency by returning 422 (already exists) on a duplicate POST, at which point ml-connector falls back to PUT; if PUT returns 404, it falls back to POST. This ensures a transaction is not double-posted in either system.

Related integrations

Connect Sage Intacct and TaxJar

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

Get started