AvaTax for FreshBooks Integration Guide

Built by Taxiom

FreshBooks Avalara
Back

This integration connects FreshBooks to your Avalara AvaTax account, calculating real-time sales tax on every FreshBooks invoice and committing the transaction to Avalara when the invoice is paid.

If you haven't already, pay the setup fee to receive your AvaTax for FreshBooks portal credentials. The portal (our integration) is how you'll connect FreshBooks to Avalara. If you have any questions, please email us at avataxforfreshbooks@taxiom.com.

Two ways to learn the integration

Take the short walkthrough, or scroll down to the written guide for step-by-step detail on every feature.

Prefer reading? Skip to the written guide ↓

Prefer to have us walk you through this on a live call? Add our Guided Setup add-on ($299) — two calls with our team, up to 45 minutes each. Add Guided Setup — $299

How this integration works

The integration is built around FreshBooks Invoices and extends to Estimates, Credit Notes, and Recurring Templates. Every time you create or update one of these in FreshBooks, the integration calculates tax through Avalara (or, for estimates, calculates without posting to filings) and writes the result back onto each line. The pattern is:

  1. Create or update an invoice in FreshBooks and assign it to a client.
  2. The integration calculates tax automatically in the background (within a few seconds of any change). Each line gets a tax rate written into taxName1 / taxAmount1.
  3. Mark the invoice paid in FreshBooks (manually or via FreshBooks payment). The integration commits the transaction to Avalara automatically so it's eligible for reporting and filing.

Once you understand that pattern, everything else in this guide is configuration and edge cases.

1. Install & Connect FreshBooks

(go to top)

Before you begin, you'll need:

  • An active Avalara AvaTax account (sandbox or production) with an Account ID, License Key, and Company Code.
  • An active FreshBooks account where you create your invoices.
  • Your AvaTax for FreshBooks portal credentials (emailed to you after the setup fee is paid).

Step 1 - Log into your portal

Sign in to avataxforfreshbooks.taxiom.com with the credentials you received. If you haven't set your password yet, use the link from the welcome email to set one.

Step 2 - Connect FreshBooks

From the dashboard, click Connect FreshBooks. You'll be redirected to FreshBooks to authorize the app. Review the scopes and approve. You'll land back on the integration portal once the install completes.

Step 3 - Enter your Avalara credentials

In the sidebar, click Avalara Credentials. Enter your Account ID, License Key, and Company Code, choose Production or Sandbox, and click Save. The portal validates the credentials against Avalara and confirms when successful.

Avalara allows only one active license key per account at a time. If you rotate the key in Avalara, any other system using the old key will need to be reconnected.

2. Configure Your Ship-From Address

(go to top)

Avalara needs to know where you're shipping from to calculate origin-based tax correctly. The integration uses the following lookup order:

  1. The business profile address configured in your FreshBooks account (Settings → Business Address).
  2. If FreshBooks doesn't have a business address set, the integration falls back to the company address you save in the AvaTax for FreshBooks portal under Company Settings.

Tax calculations cannot run without a complete ship-from address — Avalara needs an origin to determine which jurisdiction's rates to apply. If you ship from multiple warehouses, see Section 9.

An incomplete ship-from address (missing state, ZIP, or country) is the #1 cause of "tax did not calculate" errors. Always verify the business address in FreshBooks before sending invoices.

3. Your First Tax Calculation

(go to top)

Once connected, tax calculation is fully automatic. The flow:

  1. You create a new invoice in FreshBooks (or update an existing one) and assign it to a client.
  2. FreshBooks fires a webhook to the AvaTax for FreshBooks integration.
  3. The integration pulls the invoice, its line items, the client's shipping address (falling back to billing), and your ship-from address.
  4. It sends those details to Avalara for calculation.
  5. Avalara returns a tax rate and amount for each line.
  6. The integration writes the tax back onto each line in FreshBooks as a tax rate (populating taxName1 / taxAmount1).

The whole round trip usually takes a few seconds. Refresh the invoice in FreshBooks and you'll see the tax populated on each line.

Tax calculation not what you expected?

If tax calculation didn't work, check the client's shipping address — that's usually the cause. Avalara requires at minimum City, State, ZIP, and Country. You'll see an error in the Transactions log if the integration ran into an issue.

Your Avalara settings dictate the tax that comes back; the integration just sends over the transaction. If the amount looks off, check three things – which states you have turned on for tax calculation (Nexus) in AvaTax, your Item-to-Avalara-tax-code mapping, and whether you have an exemption for the customer in Avalara.

Avalara controls the tax assessment; this integration just connects FreshBooks to Avalara. See Section 15 — Frequently Asked Questions for a deeper answer.

What address is used?

The integration uses the client's shipping address (the s_* fields on the FreshBooks client record). If no shipping address is set, it falls back to the primary/billing address (the p_* fields). This matches FreshBooks' own behavior on invoices.

Discounts

Recommended: discount the line item price as you enter it, rather than using the discount field at the end of the invoice. If you are giving a customer 10% off a $500 item, enter the line at $450. Tax is then calculated directly on the discounted line price — exactly what the customer pays — and the Avalara transaction mirrors your FreshBooks invoice line for line, with no distributed amounts to reconcile.

If you do use FreshBooks' invoice-level discount field, the integration still handles it: the discount amount is sent to Avalara at the document level and spread proportionally across the lines, per Avalara's discount handling rules, on both invoices and credit notes. Tax is still calculated on the after-discount total, but because the discount is distributed across lines rather than tied to a specific one, the per-line amounts in Avalara will not match the line prices shown in FreshBooks, and per-line rounding can produce a one-cent difference from FreshBooks' displayed tax. For the cleanest records, build the discount into the line item price.

4. Estimates

(go to top)

The integration calculates tax on FreshBooks Estimates the same way it does on invoices — webhook fires, ship-to address resolves, Avalara returns the tax, and the rate is written to each line. The buyer who receives the estimate sees the full quoted price including tax.

Estimates never post a billing-eligible transaction to Avalara. Under the hood, estimates are calculated as Avalara SalesOrders — Avalara's purpose-built "non-filing" transaction type. They never count toward your liability reports and never appear in your filings. The Avalara transaction document code uses an EST- prefix (e.g. EST-12345) so it's easy to distinguish from real invoices.

When an estimate is accepted and converted to an invoice

FreshBooks lets you convert an accepted estimate into an invoice with one click. When that happens:

  1. FreshBooks fires an invoice.create webhook with the new invoice's estimateid field set to the original estimate.
  2. The integration automatically voids the original EST- SalesOrder in Avalara so there's no orphan record.
  3. The new invoice posts to Avalara as a fresh SalesInvoice (uncommitted by default).
  4. When the invoice is marked paid, the SalesInvoice commits and counts toward your filings.

The tax amount on the converted invoice is freshly calculated, not copied from the estimate. So if the customer's address, item tax codes, or jurisdictional rates changed between estimate-issued and invoice-issued, the invoice will reflect the current state — not the stale estimate state.

When an estimate is deleted

If you delete an estimate in FreshBooks (declined, expired, or just cleanup), the integration voids the matching EST- SalesOrder in Avalara automatically.

5. When Transactions Commit to Avalara

(go to top)

Tax calculation is one step; committing the transaction is what makes it count toward your Avalara filing reports. Here's how the integration handles it:

  • Invoice created or updated: Tax is calculated and the transaction is recorded in Avalara as an uncommitted SalesInvoice. Uncommitted transactions are visible in Avalara but don't count toward filings yet.
  • Invoice marked paid: The integration commits the transaction in Avalara automatically. This is the standard sales tax recognition model — tax becomes reportable at the point of payment.
  • Invoice deleted in FreshBooks: The matching Avalara transaction is voided. If the transaction was already committed and locked in a closed filing period, it's marked as DocDeleted in Avalara instead.

Configurable commit timing

The default behavior above can be changed from the Taxiom portal under Sync Settings. The three options are:

  • Commit on invoice creation — tax becomes reportable as soon as the invoice is created in FreshBooks (accrual-style).
  • Commit on payment (default) — tax becomes reportable when the invoice is paid (cash-basis).
  • Don’t commit — calculations still post to Avalara as SalesOrders for visibility but never roll up into filings.

Finding the transaction in Avalara

The Avalara document code is the FreshBooks invoice ID. Open the invoice in FreshBooks and the ID is the last segment of the URL (for example OdQg3j-1234567 → document code 1234567). Use it in the Avalara Transactions search to find the matching record. Estimates are prefixed with EST- and credit notes with CN-.

If you use cash-basis tax accounting, commit-on-paid is exactly what you want. If your accountant uses accrual-basis recognition and you want commits to happen on invoice send instead, email avataxforfreshbooks@taxiom.com — we can adjust this for your portal.

6. Credit Notes & Refunds

(go to top)

When you issue a credit note in FreshBooks to refund a paid invoice, the integration posts a matching ReturnInvoice to Avalara so your filings net out correctly. Without this, your filings would show overstated tax until you manually corrected them.

How it works

  1. You create a credit note in FreshBooks against the original invoice (Invoices → open invoice → "Issue a Credit").
  2. FreshBooks fires credit_note.create. The integration looks up the original invoice's Avalara record.
  3. If the original invoice has an Avalara record, the integration posts a ReturnInvoice (negative-tax transaction) with document code CN-{credit_note_id}, referencing the original.
  4. The negative tax shows up on Avalara liability reports for that period, offsetting the original sale.
  5. Tax is also written back to the credit note lines so the customer-facing document shows the refunded tax amount.

If the original invoice has no Avalara record

If the original invoice never made it to Avalara (e.g., calculation failed at the time, or it pre-dated the integration), the credit note can't link back to a parent transaction. In that case the integration:

  • Logs an entry in the Errors Logs page
  • Sends you an email so you can investigate
  • Does not create an orphan ReturnInvoice in Avalara — that would distort your filings

You can resolve this by either creating the matching ReturnInvoice manually in Avalara, or leaving the refund out of Avalara if the original sale was never recorded there.

If you delete a credit note

The integration listens for credit_note.delete and voids the matching CN- ReturnInvoice in Avalara automatically. If the ReturnInvoice was already committed to a closed filing period, it's marked as DocDeleted instead.

7. Item Tax Code Mapping

(go to top)

Avalara assigns different tax rates based on what's being sold. By default, every line item is treated as tangible personal property (code P0000000). For products that have a different treatment (services, software, food, etc.), map your FreshBooks Items to the right Avalara tax code in the portal.

How to map your items

From the portal, go to Item Tax Code Mapping. The page lists all the Items you've defined in FreshBooks (under Settings → Items & Services). Next to each Item, choose the Avalara tax code that best fits.

Common tax codes

Tax CodeDescriptionWhen to use
P0000000General Tangible Personal PropertyDefault for unmapped items; physical goods with no special rules
SW054000Software as a Service (SaaS)Cloud-hosted software with no download
SW052000Pre-written software, electronically deliveredDownloadable software
SP000000Services (general)Generic professional services
FR020100Shipping - taxableShipping line items where shipping is taxable
NTNon-taxableItems that are never taxable

If you don't map an item, the integration uses Avalara's general tangible personal property code (P0000000). For most generic physical-goods sellers this is fine. For services or software, mapping is strongly recommended.

You can browse the full Avalara tax code catalog at taxcode.avatax.avalara.com.

8. Exemptions & Customer Codes

(go to top)

You have two ways to handle tax-exempt customers. The first method is strongly recommended because it lets Avalara verify the exemption certificate at calculation time. The second is a manual override — use it only when the first method isn't an option.

Method 1 (recommended): Exemption certificates in Avalara, matched by FreshBooks client ID

The integration automatically passes the FreshBooks client's ID to Avalara as the customer code on every transaction. That means if you upload exemption certificates in Avalara against that same customer code, Avalara's tax engine will check the certificate's validity on every calculation and apply the exemption automatically — only when the certificate is current and applicable to the jurisdiction.

The flow:

  1. Find the FreshBooks client's ID (visible in the client record URL).
  2. In Avalara, go to Customers, create or open the customer record matching that FreshBooks client ID, and upload the exemption certificate (resale, nonprofit, government, etc.).
  3. Avalara now checks the certificate on every tax calculation for that customer. If it's valid for the jurisdiction and applicable to the transaction, tax comes back as $0. If it's expired or not applicable, tax calculates normally.

This is the better path because Avalara owns the certificate validation — it tracks expirations, jurisdictional applicability, and produces an audit trail that holds up under exam.

If you have a high volume of certificates to manage (uploads, expirations, multi-jurisdiction tracking, customer self-service), Avalara's full Exemption Certificate Management product or ExemptHQ from Taxiom add purpose-built tooling on top of the same matching mechanism.

Method 2 (fallback): Entity use code on the client

If you don't have certificate management set up in Avalara yet, or you need a quick manual override, flag the FreshBooks client as exempt in the portal and assign an entity use code (Avalara's standard exemption categories: A = Federal government, B = State/local government, C = Tribal government, D = Foreign diplomat, E = Charitable, F = Religious/educational, G = Resale, etc.). Once flagged, every invoice for that client will be calculated as exempt.

Why this is the fallback, not the recommended path: Setting an entity use code tells Avalara "trust me, this customer is exempt" — Avalara will mark the transaction as exempt without ever checking whether a valid certificate is actually on file. That's faster to set up, but it leaves you exposed in an audit if you don't have the backing documentation. Whenever possible, upload the actual certificate in Avalara (Method 1) and let the tax engine do the verification.

9. Multiple Ship-From Locations

(go to top)

If you ship from more than one location, you can register each warehouse in the portal's Ship-From Locations page and route specific clients or items to specific origins. Avalara uses the ship-from address to determine origin-based tax in states where that matters.

In the portal, go to Ship-From Locations, then add each location with a code (e.g., TX01), name, and full address. If no location is selected for a particular invoice, the default ship-from address from FreshBooks (or the portal's Company Settings fallback) is used.

10. Recurring Invoices & Templates

(go to top)

FreshBooks Recurring Templates define a schedule that generates new invoices on a recurring cadence (weekly, monthly, annually). The integration handles both the template itself and the invoices it generates — differently for each.

Generated invoices: full tax calc

Each time the schedule fires, FreshBooks creates a brand new invoice. That invoice fires invoice.create and runs through the standard tax flow:

  • Tax calculates fresh against the client's current ship-to address and current Avalara rates — not a stale snapshot from when the template was set up.
  • When the generated invoice is marked paid (manually or via FreshBooks auto-payment), the transaction commits to Avalara just like a one-off invoice.

If you change the line items, price, or client on the recurring template, future generated invoices will reflect those changes and the integration will recalculate tax against the new state.

Template-level ship-to validation

The integration also listens for recurring.create and recurring.update — events that fire when you create or edit the template itself, not when an invoice generates from it. We never calculate tax on the template directly (it's a schedule, not a document), but we do check the linked client's ship-to address.

If the client is missing any of city, state, ZIP, or country, the integration writes an entry to the Errors Logs page and emails you a warning. This catches the problem before the schedule fires and starts generating a string of tax-less invoices. Common scenario:

  • You create a recurring template for Acme on Jan 1, but Acme's client record in FreshBooks has no ship-to country.
  • Without the validation, every monthly invoice generated would silently skip tax calc and email you a failure notice on each cycle.
  • With the validation, you get one email at template-creation time naming the missing fields. Fix the client address in FreshBooks before the first invoice fires and tax will calculate normally from there.

For subscription businesses, make sure the customer's billing address matches the shipping address — or that the shipping address is correct on every renewal. A stale shipping address is the #1 cause of "we moved but tax didn't change" issues.

11. Validating Customer Addresses

(go to top)

Avalara's tax accuracy depends entirely on the quality of the address you pass it. A wrong ZIP code can mean a wrong rate. Here's how to keep addresses clean:

  • Always populate the state and ZIP on FreshBooks clients — even for international clients with no US tax obligation.
  • For US clients, the ZIP should be 5 digits. ZIP+4 (e.g., 78704-5301) is even better — Avalara routes to the right special district based on the +4 suffix.
  • For Canadian clients, use the postal code format A1A 1A1.
  • If you import clients from another system, run an address-validation pass before going live. Avalara's Address Validation API can clean up addresses in bulk.

Bulk address validation in Excel

If you have a large list of FreshBooks clients with addresses to clean up — or you want a one-time scrub before going live — we recommend Validate and Fix Addresses in Excel. Export your client addresses from FreshBooks, run them through the tool to catch missing ZIPs, wrong states, and unverifiable street numbers, then re-import the corrected addresses back into FreshBooks. This is separate from the AvaTax for FreshBooks integration and is a one-time data-cleanup step, not something the integration calls into.

The integration logs a warning when it detects an incomplete address, but it will still attempt calculation using whatever it has. Bad addresses lead to wrong tax — and wrong tax leads to filing problems.

12. Overriding Avalara's Tax Calculation

(go to top)

In rare cases, you may need to override Avalara's calculation — for example, when re-issuing an old invoice for a closed tax period, or when you've already paid tax on a transaction outside the system.

FreshBooks lets you manually edit the taxName1 / taxAmount1 fields on a line directly after the integration writes them. However: any subsequent update to the invoice will trigger a recalculation that overwrites your manual edit.

For permanent overrides, email avataxforfreshbooks@taxiom.com. We can configure your portal to skip calculation for specific invoices, specific date ranges, or specific clients.

Self-serve per-invoice override: open Invoice Tax Overrides in the portal sidebar. Enter the FreshBooks invoice ID (visible in the invoice URL, e.g. my.freshbooks.com/.../invoices/176935), the override tax dollar amount, and an optional reason note. On the next sync of that invoice the integration sends taxOverride { type: TaxAmount } to Avalara so the supplied amount becomes the recorded tax. Avalara still requires active nexus in the destination jurisdiction or the override is rejected with TaxOverrideError. Removing the row on that page restores Avalara’s calculated value on the next sync.

13. Transactions Log & Errors Log

(go to top)

The portal includes a Transactions page that shows every interaction between FreshBooks, the integration, and Avalara. For each invoice you can see:

  • When tax was calculated
  • What ship-from and ship-to addresses were used
  • The Avalara document code and total tax
  • Whether the transaction is uncommitted or committed
  • The full request and response payloads (helpful for debugging)

The full audit trail for failures lives in Errors Logs in the portal. Every failed calculation logs the exception type, message, FreshBooks invoice ID, and timestamp.

The most common error categories:

  • Address incomplete — the client is missing street, city, state, or postal code
  • Country required — the country field is blank on the client
  • Tax code not found — an Item is mapped to an Avalara tax code that Avalara doesn't recognize
  • Avalara 401 — credentials are invalid; check Avalara Credentials in the portal
  • No ship-from address — neither FreshBooks Business Settings nor portal Company Settings has a complete address

14. Self-Serve Admin & Receipts

(go to top)

The Account Settings page in the portal sidebar is where you manage your account details and find your billing receipts.

  • Profile & Email — update your name, login email, and company name
  • Change Password — update your portal password
  • Receipts — view and download the receipt for your AvaTax for FreshBooks integration setup. Click View Receipt to open the Stripe-hosted receipt page where you can download a PDF.

15. Frequently Asked Questions

(go to top)

What actually controls whether tax is calculated on a transaction?

Three things — and all three live in your Avalara account, not in this integration:

  1. Whether your Avalara account has that state turned on for tax calculation. If you're not registered to collect tax in a state (no nexus), Avalara returns $0 tax for transactions shipping to that state. The integration sends the transaction either way — Avalara decides whether to apply tax based on which states you've enabled.
  2. Whether the product or service you're selling is taxable in the destination jurisdiction. Tangible goods are usually taxable everywhere; services, digital downloads, food, and clothing vary widely by state. The Avalara tax code on each Item tells Avalara what category to apply.
  3. Whether your customer is taxable at all. Exempt customers (resale, nonprofit, government, etc.) get $0 tax either via Avalara certificate matching (matched on the FreshBooks client ID), or via the entity use code shortcut in the portal.

The integration's job is to send the right transaction details to Avalara — what's being sold, where it's shipping to, who the buyer is. Avalara then applies all three rules above and tells us the tax amount. If you're seeing $0 tax when you expected a charge (or a tax amount you didn't expect), the answer is almost always in those three Avalara settings, not in the integration.

Why isn't the tax amount shown in FreshBooks' summary tax field?

FreshBooks calculates the invoice's total tax by summing each line's tax. The integration writes a tax rate onto each line (taxName1 / taxAmount1), and FreshBooks rolls those line-level taxes into the invoice total automatically. You'll see the per-line tax on each line and the sum at the bottom of the invoice.

How long does a tax calculation take?

A few seconds for the typical case. The clock starts when FreshBooks fires the invoice webhook and ends when the tax is written back to each line. If you don't see the tax after 30 seconds, check the Transactions or Errors log in the portal.

I got a "duplicate transaction" error in Avalara. What does that mean?

This happens if the same invoice gets re-sent to Avalara. The integration uses the FreshBooks invoice ID as the document code, so duplicates are usually safe to ignore. If you intentionally re-created an invoice in FreshBooks (different invoice number, same content), Avalara will treat it as a new transaction.

I deleted an invoice — did the Avalara transaction void?

Yes — the integration listens for FreshBooks invoice.delete events and voids the matching Avalara transaction automatically. If the transaction was already committed and locked in a closed filing period, it's marked as DocDeleted in Avalara instead.

Can I label the tax line something other than "Sales Tax"?

Yes. The integration writes the value of taxName1 on each line. By default this is "Sales Tax"; for VAT-style markets, email avataxforfreshbooks@taxiom.com and we'll change the label on your portal to "VAT", "GST", or whatever fits.

Why does my Avalara dashboard show "Uncommitted" SalesInvoice transactions?

Before an invoice is paid, the integration records the transaction in Avalara as uncommitted so you can see and review it without it counting toward your filings. When the invoice is marked paid in FreshBooks, the integration commits the transaction automatically so it's eligible for reporting and filing.

16. Troubleshooting & Support

(go to top)

If something isn't working, here's the order to check:

  1. Check the Transactions log for the invoice. If you don't see an entry, the webhook didn't reach the integration — usually a connection or scope issue.
  2. Check the Errors Logs in the portal sidebar. The most recent error usually has the full context (which invoice, what failed).
  3. Confirm your Avalara credentials are valid — re-save them in the portal if unsure (especially if you've rotated the license key in Avalara).
  4. Confirm Company Settings has a default ship-from address (or that FreshBooks Business Settings has one). Calculations can't run without one.
  5. Confirm the client has a complete shipping address in FreshBooks (street, city, state, ZIP, country).

Tax calculated, but the rate looks wrong

  • Verify the client's shipping address state and ZIP are correct.
  • Verify the Item is mapped to the correct Avalara tax code. Software billed as tangible goods (P0000000) will get the wrong rate in some states.
  • Check Avalara for any nexus or rate overrides you've configured at the company level.

If you've checked all of the above and tax still isn't calculating, email avataxforfreshbooks@taxiom.com with the FreshBooks invoice ID and a brief description of what you expected vs. what happened. We respond same-day, usually within a couple of hours.