ml-connector
QuickBooks OnlineTaxJar

QuickBooks Online and TaxJar integration

Small-to-mid-market businesses use QuickBooks Online to manage invoices and bills. TaxJar calculates sales tax rates and automates reporting to state tax agencies. Connecting the two keeps your sales transaction data current in TaxJar, ensures tax is calculated correctly per jurisdiction, and automates the periodic returns filed to state tax authorities. ml-connector moves paid invoices from QuickBooks Online into TaxJar and brings calculated tax back for reconciliation.

How QuickBooks Online works

QuickBooks Online exposes invoices, customers, items, accounts, departments, and journal entries through the QuickBooks Online Accounting API (v3) over REST. Authentication uses OAuth 2.0 with hourly-expiring access tokens and rotating refresh tokens that expire within 24-26 hours. QuickBooks Online publishes webhook events when invoices, payments, and journal entries are created, updated, or voided, though webhook payloads contain only the entity ID and operation type - the full record must be fetched separately. A CDC (Change Data Capture) endpoint is also available for polling with 30-day history.

How TaxJar works

TaxJar exposes transaction endpoints, tax rate lookups, and nexus region tracking through its REST API, secured with a static API token in the Authorization header. The API is versioned via an x-api-version header using date format (e.g. 2022-01-24). TaxJar does not support webhooks or push events - all integrations are pull-based or merchant-initiated. Real-time tax calculation happens via POST to the /taxes endpoint at checkout, while completed transactions are POSTed or PUT to the /transactions endpoint after fulfillment. Sandbox environments are available on Professional plans and are stateless - they validate request format only and do not persist data.

What moves between them

The main flow runs from QuickBooks Online to TaxJar. When an invoice is marked as paid in QuickBooks Online, ml-connector reads the invoice details - customer, line items, total amount, ship-to address, and any customer tax exemption status - and POSTs the transaction to TaxJar for calculation and nexus tracking. TaxJar returns the calculated tax rate and liability. ml-connector then creates a journal entry in QuickBooks Online with the tax amount, posted to the sales tax liability account, so QuickBooks Online stays current with what TaxJar has calculated and reported to the states. The sync runs on a schedule tied to your month-end close cycle, with catch-up polls for any missed transactions.

How ml-connector handles it

ml-connector stores both credential sets encrypted: QuickBooks Online OAuth credentials with automatic refresh-token rotation, and TaxJar API tokens. On the QuickBooks Online side, ml-connector subscribes to Payment and Invoice webhook events and also polls the CDC endpoint to catch any missed transactions due to webhook latency or loss. When an invoice reaches paid status, ml-connector fetches the full invoice record from QuickBooks Online, extracts line items and the customer's ship-to address, and checks for any exemption status. It then POSTs the transaction to TaxJar's /transactions endpoint with item descriptions, quantities, unit prices, and the destination address. TaxJar validates the address and returns the calculated tax rate and liability. If a transaction already exists (detected via a 422 Unprocessable Entity response), ml-connector falls back to a PUT to update it. The calculated tax liability is then written back into QuickBooks Online as a journal entry in the sales tax payable account, reconciled to the invoice, so your tax reserve is accurate month-to-month. Retries back off on rate limits, and every record carries an audit trail showing the invoice ID, tax calculation, and timestamp.

A real-world example

A small e-commerce business sells products through an online store and records each order as an invoice in QuickBooks Online. Before the integration, the accounting team manually entered each week's sales total into a separate tax calculator, checked it against QuickBooks Online, and then uploaded the transactions to TaxJar for state filing. Tax liability was often mismatched by the time month-end arrived because transactions were out of sync. With QuickBooks Online and TaxJar connected, each paid invoice flows automatically to TaxJar the same day, tax is calculated per jurisdiction, and the liability is posted back as a journal entry in QuickBooks Online. The sales tax account reconciles to TaxJar's report every month, and state returns are filed on time with accurate numbers.

What you can do

  • Post completed sales transactions from QuickBooks Online to TaxJar with customer, line items, and ship-to address for real-time tax calculation.
  • Retrieve calculated tax rates and liability from TaxJar and create reconciling journal entries in QuickBooks Online's sales tax account.
  • Handle QuickBooks Online OAuth token refresh and TaxJar API token authentication, with encrypted storage of both credential sets.
  • Poll QuickBooks Online webhooks and the CDC endpoint to catch paid invoices and sync them to TaxJar on a monthly schedule aligned with your close cycle.
  • Retry on rate limits and 422 (duplicate transaction) responses, with full audit trail for every transaction posted and every tax liability recorded.

Questions

Which direction does data move between QuickBooks Online and TaxJar?
The main flow is from QuickBooks Online to TaxJar. Paid invoices with customer and line-item detail move to TaxJar for tax calculation and nexus tracking. The calculated tax rate and liability flow back into QuickBooks Online as a reconciling journal entry in the sales tax payable account.
How does ml-connector handle QuickBooks Online's webhook latency and the lack of webhooks in TaxJar?
ml-connector subscribes to QuickBooks Online Payment and Invoice events but also polls the CDC (Change Data Capture) endpoint with 30-day lookback to catch any missed transactions. TaxJar has no webhooks, so ml-connector polls TaxJar's transaction status after posting to confirm receipt and to fetch the final calculated tax liability.
What happens if a transaction already exists in TaxJar when ml-connector tries to post it?
If TaxJar returns a 422 (Unprocessable Entity) indicating the transaction exists, ml-connector falls back to a PUT request to update the existing transaction with any new details. If the PUT returns a 404 (not found), it retries the POST, ensuring the transaction is recorded in both systems without duplication.

Related integrations

Connect QuickBooks Online and TaxJar

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

Get started