POST /public/v2/taxes/calculate/ → map tax fields → POST /public/v2/invoices/. The same flow applies to bills using vendor_id in place of customer_id.
Prerequisites
- V2 API (
/public/v2/...) X-API-KEYheader with your organization’s API key (authenticating your requests)- The company is set up for the correct tax regime (GST, VAT, or US sales tax)
- The customer (or vendor) has
is_taxableset totruewhen tax should apply
Step 1: Resolve IDs
Look up the company, customer or vendor, and item IDs the calculate call needs:Step 2: Calculate tax
Send the resolved IDs and item lines to the calculate endpoint:company_idcustomer_id(money-in, e.g. invoices) orvendor_id(money-out, e.g. bills), not both
items: each withitem_id,quantity, andunit_price(item_idmay benullfor a vendor expense line)transaction_buyer_address: the destination address, required for US sales taxtransaction_dateandcurrency_code: required for US sales taxsupply_date: filters VAT/GST rates by their validity window
type is one of:
For GST and VAT, the first calculate call often returns
available_rates. Pick a rate, send it on the line as selected_gst_tax_rate_id or selected_vat_rate_id, then calculate again with that rate selected.
Step 3: Map the result onto each invoice line
Copy each field from the calculator response onto the matching field in the invoice line’stax object:
Also carry the line amount over: calculator
unit_price → invoice line rate.
Step 4: Create the invoice
Send the mapped tax fields on each line when you create the invoice:shipping_address on the invoice for fulfillment; it does not replace the calculate step.
Canada GST example (two calculate calls)
GST and VAT regimes need a second calculate call once a rate is selected. Call A: list available rates Calculate without a selected rate first to see what DualEntry offers for this address:type: "GST" with data.place_of_supply ("ON") and data.available_rates listing candidate rate IDs. Pick one (for example, the Ontario HST rate) from available_rates or from GET /public/v2/gst-tax-rates/.
Call B: calculate again with the selected rate
Add the chosen rate ID to the line and calculate again to get the final tax amounts:
tax_code, tax_rate, tax_amount, and selected_gst_tax_rate_id set. Map those onto the invoice as in Step 3, then create the invoice using the values from call B.
US sales tax
- Send
transaction_buyer_address(includeregionandpostal_code),transaction_date, andcurrency_codeon calculate. - The response
typeisSALES_TAX. - Copy
tax_code,tax_rate, andtax_amountonto the line’staxobject. - Create the invoice.
type: "NONE" with a reason. Fix the address and calculate again before creating the invoice.
VAT
- The first calculate call returns
available_rates. - Send
selected_vat_rate_idon the line and calculate again. - Set the invoice line’s
tax.vat_rate_idfrom the sameselected_vat_rate_id. - Create the invoice.
If calculate returns an error
The calculate endpoint returns errors for a few common mistakes:
Fix the request and calculate again. A
NONE result is not itself an error: it means DualEntry could not determine tax for this request, and the reason field says why.
Checklist before go-live
- Call calculate before creating the invoice or bill
- Pass the buyer/shipping address on calculate as
transaction_buyer_address - For GST/VAT, select a rate from
available_ratesand calculate a second time - Copy every mapped tax field onto each line’s
taxobject - Confirm the invoice response shows
items[].taxwith the expected code, rate, and amount