ml-connector
XeroTaxJar

Xero and TaxJar integration

Xero runs your accounting and invoicing. TaxJar calculates your sales tax obligations by state and jurisdiction. Connecting them keeps your tax records in sync with your ledger. Invoices created in Xero flow to TaxJar for real-time tax calculation, and the calculated tax liabilities post back into Xero as manual journal entries allocated to the correct tax accounts. ml-connector handles Xero's webhook routing and token refresh, stores TaxJar credentials securely, and moves the data on a schedule you control.

How Xero works

Xero is a cloud-based accounting platform that exposes invoices, credit notes, contacts, payments, accounts, and purchase orders through the Xero Accounting API, a REST service served over HTTPS. Authentication uses OAuth2 with access tokens that expire after 30 minutes; ml-connector can request refresh tokens with offline_access to renew the session. Webhooks deliver CREATE and UPDATE events for invoices, credit notes, and other records, but they contain only metadata and a resource ID, so a follow-up GET request fetches the full payload. All calls must include a Xero-tenant-id header to target the correct organization. The API is rate-limited to 60 requests per minute per tenant and 5 concurrent calls.

How TaxJar works

TaxJar is a cloud-based sales tax compliance platform that exposes tax calculations, transaction reporting, nexus regions, and tax rates through a REST API served over HTTPS. Authentication uses API tokens that merchants generate from their TaxJar account and pass in the Authorization header; there is no OAuth2, so integrations must store tokens encrypted at rest. TaxJar does not publish webhooks or push events to external systems, so all data movement is poll-based or merchant-initiated through POST and PUT calls. Calculations are performed server-side via the /taxes endpoint, which accepts order line items and returns real-time tax by jurisdiction. Transaction endpoints do not count toward monthly API thresholds, and a sandbox environment is available for testing.

What moves between them

Xero invoices and credit notes flow into TaxJar for tax calculation. When an invoice is created or updated in Xero, ml-connector reads the full record and posts it to TaxJar's /transactions/orders endpoint with line items, customer address, and shipping detail. TaxJar calculates the tax amount by jurisdiction and returns the liability. ml-connector then posts the calculated tax as a manual journal entry back into Xero's general ledger, allocated to the configured tax payable account for that state or region. Credit notes follow the same path, posted to TaxJar's /transactions/refunds endpoint and posted back to Xero to offset the original tax liability. The cycle runs on a schedule tied to your accounting close period, with retries if a Xero or TaxJar call fails.

How ml-connector handles it

ml-connector subscribes to Xero invoice and credit note webhooks. When an event arrives, it fetches the full record from Xero using the resource ID in the webhook and the required Xero-tenant-id header. It extracts the customer address, line items, and tax jurisdiction from the invoice and assembles a call to TaxJar's /taxes endpoint to calculate the liability. TaxJar returns the tax amount broken down by jurisdiction, and ml-connector posts that tax as a manual journal entry into Xero's general ledger, splitting the debit and credit across the correct tax accounts. If a TaxJar call returns an error (such as an invalid address), ml-connector retries with exponential backoff; if Xero returns 401, it refreshes the OAuth2 token and retries. Xero's 60-request-per-minute rate limit is respected, and every transaction carries an audit trail for reconciliation. TaxJar API tokens are stored encrypted and refreshed only when invalid or expired.

A real-world example

A small online retail business runs Xero for accounting and invoicing and uses TaxJar for sales tax compliance across ten states. Before integration, the finance team exported invoices from Xero each week, entered them manually into TaxJar's dashboard to calculate tax by state, then copied the tax figures back into Xero as journal entries, a process that took two hours per week and was error-prone. With Xero and TaxJar connected, each invoice posts to TaxJar automatically, the tax liability calculates in real time, and the journal entry lands in Xero without manual re-entry. The compliance calendar is synchronized with the accounting calendar, and month-end close starts with tax liabilities already correct.

What you can do

  • Post Xero invoices and credit notes to TaxJar for real-time sales tax calculation by jurisdiction.
  • Create manual journal entries in Xero for calculated tax liabilities, allocated to the correct tax payable accounts.
  • Map customer addresses and line items from Xero to TaxJar's tax calculation endpoint and handle address validation errors.
  • Refresh Xero OAuth2 tokens and manage rate limits, with automatic retries on failed posts.
  • Track every invoice-to-tax-to-journal flow in an audit log for reconciliation and compliance reporting.

Questions

How does ml-connector handle Xero webhook events for invoices and credit notes?
When Xero sends a webhook event for an invoice or credit note, it includes only metadata and a resource ID. ml-connector uses that ID to fetch the full record from Xero using the Accounting API and the required Xero-tenant-id header, then extracts the customer address, line items, and jurisdiction to calculate tax in TaxJar.
Does TaxJar's lack of webhooks mean transactions are delayed?
No. ml-connector subscribes to Xero webhooks so it detects invoices immediately, then posts them to TaxJar in real time for calculation. You can also configure ml-connector to poll Xero on a schedule if you prefer event-driven operation or have invoices created outside of Xero that you want to report.
What happens if the address in a Xero invoice is invalid or incomplete for TaxJar?
TaxJar's address validation endpoint will return an error if the address does not match a recognized jurisdiction. ml-connector logs the error, retries with exponential backoff, and surfaces the issue in the audit log so you can correct the address in Xero and reprocess the invoice.

Related integrations

Connect Xero and TaxJar

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

Get started