ml-connector
XeroAvalara

Xero and Avalara integration

Xero handles accounting, invoicing, and bills. Avalara AvaTax calculates sales and use tax across jurisdictions. Connecting the two means every Xero invoice and bill is sent to AvaTax for an accurate tax determination, and the calculated amounts come back onto the Xero record without manual tax entry. Because AvaTax holds no vendors, accounts, or invoices of its own, Xero is the system of record and AvaTax is the tax engine it calls. ml-connector handles the different APIs and authentication on each side and moves the data on a schedule you control or as Xero webhooks fire.

How Xero works

Xero exposes contacts, invoices, bills, purchase orders, payments, accounts, items, and tracking categories through the REST Accounting API at api.xero.com over HTTPS. Authentication is OAuth 2.0 authorization code flow, with 30-minute access tokens and 60-day refresh tokens, and every call carries a Xero-tenant-id header to target one organization. List endpoints use page-based pagination at 100 records per page, and an If-Modified-Since header supports delta sync. Xero pushes signed webhook events for resources such as Invoice and Contact, but payloads contain metadata only, so a follow-up GET is required to read the full record.

How Avalara works

Avalara AvaTax exposes a REST v2 API at rest.avatax.com over HTTPS, with a separate sandbox host. Authentication is HTTP Basic, using a numeric account ID and a per-account license key that is preferred for connectors because it survives user password changes. The central object is the transaction, created with CreateTransaction or the idempotent CreateOrAdjustTransaction, and committed, voided, adjusted, or refunded by ID. AvaTax has no vendor, purchase order, payment, or GL account objects, so those arrive as string codes on transaction lines. AvaTax does not push webhooks; its Notifications resource is pull-only, so the ERP triggers the work.

What moves between them

The flow runs from Xero into Avalara. When a Xero invoice or bill is authorised, ml-connector reads it and posts it to AvaTax: ACCREC invoices become SalesInvoice transactions and ACCPAY bills become PurchaseInvoice transactions for self-assessed use tax, with line amounts, item or account codes, the customer code, and ship-from and ship-to addresses. AvaTax returns the calculated tax, which ml-connector writes back onto the Xero invoice. Xero Invoice webhooks trigger the work as records change, and a scheduled poll using If-Modified-Since backfills anything a webhook missed. AvaTax is a calculation service, so no vendor or account master is written back into Xero.

How ml-connector handles it

ml-connector stores both credential sets encrypted, refreshing the Xero OAuth access token before its 30-minute expiry and sending the Avalara account ID and license key as a Basic header on every call. Xero accounts and items map to AvaTax tax codes so each line is classified correctly, and the Xero invoice number is used as the AvaTax document code, which acts as its idempotency key. CreateOrAdjustTransaction is used so a safe retry updates an uncommitted transaction in place rather than duplicating it. Once a transaction is committed in AvaTax its code is reserved, so a later change voids and re-creates rather than overwriting. Xero webhook payloads carry only an ID, so ml-connector verifies the x-xero-signature HMAC against the raw body, returns 200 quickly, then performs a follow-up GET for the full invoice. Addresses are validated through AvaTax address resolve before calculation, since an invalid address fails the tax call. Xero rate limits return 429 with a Retry-After header and AvaTax returns 429 without one, so ml-connector backs off with jitter and retries, and every record carries a full audit trail with error replay.

A real-world example

A US-based online retailer with about 60 staff runs Xero for accounting and sells into many states with sales tax nexus. Before the integration, staff looked up tax rates by hand and keyed them onto Xero invoices, which produced wrong rates on cross-state orders and a slow, error-prone filing season. With Xero and Avalara connected, every authorised invoice is sent to AvaTax with the customer's shipping address, the correct jurisdictional tax comes back onto the Xero record automatically, and the committed transactions in AvaTax give a clean basis for returns. The manual rate lookups disappear and tax on each invoice is consistent and defensible.

What you can do

  • Post authorised Xero invoices and bills to AvaTax as SalesInvoice and PurchaseInvoice transactions for accurate tax calculation.
  • Write AvaTax calculated sales and use tax back onto the matching Xero invoice.
  • Map Xero accounts and items to AvaTax tax codes so each line is classified correctly.
  • Bridge Xero OAuth 2.0 tokens and Avalara HTTP Basic authentication, refreshing Xero tokens automatically.
  • Trigger on Xero invoice webhooks with a scheduled If-Modified-Since poll as backfill, with retries and a full audit trail.

Questions

Which direction does data move between Xero and Avalara?
Data moves from Xero into Avalara. Xero is the system of record, and its invoices and bills are posted to AvaTax as transactions for tax calculation. The calculated tax is written back onto the Xero record, but AvaTax holds no vendor or account master to send the other way.
How does the integration avoid duplicate tax transactions on retries?
ml-connector uses each Xero invoice number as the AvaTax document code, which is AvaTax's idempotency key. It posts through CreateOrAdjustTransaction, so retrying an uncommitted transaction updates it in place instead of creating a duplicate. Once a transaction is committed its code is reserved, so a later change is handled by voiding and re-creating rather than overwriting.
Does Avalara push events back to Xero?
No. AvaTax does not push webhooks, and its Notifications resource is pull-only, so the ERP side drives the work. ml-connector listens for Xero invoice webhooks and also runs a scheduled poll using the If-Modified-Since header to catch any records a webhook missed.

Related integrations

Connect Xero and Avalara

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

Get started