ml-connector
Sage 100Avalara

Sage 100 and Avalara integration

Sage 100 runs accounting, sales orders, and purchasing on a server in your office. Avalara AvaTax calculates sales and use tax across thousands of jurisdictions in the cloud. Connecting the two replaces manual tax lookups and stale rate tables with live, address-accurate tax on every document. Sales orders and AR invoices flow from Sage 100 to AvaTax for calculation, the tax comes back onto the Sage 100 document, and committed sales feed Avalara's records for return filing. ml-connector handles the on-premises bridge, the very different auth on each side, and the polling that Sage 100 requires.

How Sage 100 works

Sage 100 is on-premises only and has no native cloud API. Its eBusiness Web Services SOAP surface covers just Sales Orders and Customers, while the Business Object Interface (BOI) reaches the full AR, AP, GL, PO, and inventory model but runs as COM on the server and cannot be called over HTTP directly. The realistic path is a local Windows agent that wraps BOI and exposes an HTTPS endpoint, authenticated with an agent API key, with SOAP authenticating by username and password passed inline on each call. Sage 100 has no webhooks, so records are read by polling DateLastUpdated and document date fields, and every call requires the three-character company code.

How Avalara works

Avalara AvaTax is a cloud service exposed as a REST v2 API, JSON over HTTPS, using HTTP Basic authentication built from an account ID and a license key. Its central object is the transaction, created at POST /api/v2/transactions with a type such as SalesInvoice or PurchaseInvoice, line items carrying amount and tax code, and ship-from and ship-to addresses that drive the rate. AvaTax is tax-only and stores no vendors, purchase orders, GL accounts, or payments; those are passed as string references. It pushes no webhooks, so reconciliation is done by polling list endpoints, and the document code field acts as the idempotency key.

What moves between them

The main flow runs from Sage 100 into Avalara. As sales orders and AR invoices are created or updated in Sage 100, ml-connector reads them through the agent and posts each one to AvaTax as a transaction to calculate tax, then writes the returned tax amount back onto the Sage 100 document. AP invoices can be sent as PurchaseInvoice transactions so AvaTax self-assesses use tax. Customers and inventory items move the same direction so AvaTax has the customer codes for exemption certificates and the tax codes for each product. Committed sales stay recorded in AvaTax for return filing, and AvaTax is treated as the system of record for tax, so ml-connector does not write accounting entries back from it.

How ml-connector handles it

ml-connector stores both credential sets encrypted, calls the Sage 100 agent with its API key, and sends the AvaTax account ID and license key as a Basic auth header on every request, switching the sandbox base URL for production once live credentials are in place. Because Sage 100 has no webhooks, it polls the agent on a schedule using DateLastUpdated and document dates, scoped to the company code, rather than waiting for a push. Each Sage 100 document number becomes the AvaTax transaction code, and ml-connector uses createOrAdjust so an uncommitted transaction is updated in place and a retry never records tax twice. Customers map to AvaTax customer codes and Sage 100 items map to AvaTax tax codes so each line is classified correctly, and segmented Sage 100 GL accounts are parsed defensively. AvaTax rate limits return HTTP 429 with no Retry-After header, so ml-connector backs off with jitter and retries, and a committed AvaTax code cannot be reused, so a change to a posted document is handled by void and re-create rather than overwrite. Every record carries a full audit trail and can be replayed if a call fails.

A real-world example

A regional building-materials distributor with about 120 staff runs Sage 100 on a server at its main warehouse and ships to contractors across several states. Before the integration, the AR clerk looked up tax rates by hand and kept rate tables in a spreadsheet, which drifted out of date and produced under- and over-charges that surfaced during state audits, while exemption certificates for tax-exempt contractors were tracked in a filing cabinet. With Sage 100 and Avalara connected, every sales order is priced with the exact rate for the ship-to address the moment it is entered, exempt customers are matched to their AvaTax certificates automatically, and committed invoices are already recorded in Avalara when returns come due. The spreadsheet is gone and audit exposure drops.

What you can do

  • Calculate live sales tax on Sage 100 sales orders and AR invoices using the ship-to address, and write the result back onto the document.
  • Send Sage 100 AP invoices to AvaTax as purchase transactions so use tax is self-assessed.
  • Map Sage 100 customers to AvaTax customer codes and items to AvaTax tax codes so every line is classified correctly.
  • Bridge the Sage 100 local-agent API key and AvaTax HTTP Basic auth, using each document number as the AvaTax code for safe retries.
  • Poll Sage 100 on a schedule, because it has no webhooks, with backoff on AvaTax rate limits and a full audit trail on every record.

Questions

Which direction does data move between Sage 100 and Avalara?
The main flow is Sage 100 into Avalara. Sales orders, AR invoices, AP invoices, customers, and items move from Sage 100 to AvaTax, and the calculated tax is written back onto the Sage 100 document. AvaTax is the system of record for tax, so ml-connector does not push accounting entries back into Sage 100 from it.
How does the integration reach Sage 100 if it has no cloud API?
Sage 100 is on-premises and its full accounting model is only reachable through the Business Object Interface, which runs as COM on the server. A local Windows agent on the customer server wraps that interface and exposes an HTTPS endpoint, and ml-connector calls the agent with an API key. The narrow SOAP surface covers only Sales Orders and Customers, so the agent is required for AP and GL data.
How are duplicate tax records avoided when a document is retried?
ml-connector uses each Sage 100 document number as the AvaTax transaction code and submits through createOrAdjust, so an uncommitted transaction is updated in place rather than duplicated. Because Sage 100 has no webhooks, records are read by polling, and a committed AvaTax code cannot be reused, so a change to a posted document is handled by void and re-create.

Related integrations

Connect Sage 100 and Avalara

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

Get started