Skip to main content
POST
Calculate tax
On create and update, DualEntry keeps the tax you send on each line unless you set auto_calculate_tax to required. That setting calculates native US sales tax using DualEntry’s tax engine, and Avalara US sales tax, VAT, and GST, then replaces the line tax. On a record create or update with auto_calculate_tax set to required, a result that is DualEntry’s own VAT or GST fails with 422. A calculation that cannot finish also fails with 422. Use this endpoint to preview the tax, to check the amounts after you choose a VAT or GST rate, or to copy the result onto lines you save yourself. Required:
  • company_id
  • customer_id or vendor_id, and not both
Usually also send:
  • items, with item_id, quantity, and unit_price on each line
  • transaction_buyer_address, transaction_date, and currency_code for US sales tax
  • supply_date, to keep the VAT and GST rates that are valid on that date
The response type is SALES_TAX, VAT, GST, or NONE. NONE is still HTTP 200, and the body gives the reason, such as a missing buyer address. Copy each result line onto items[].tax, and onto expenses[].tax when the record has expenses:
  • tax_code to tax.code
  • tax_rate to tax.rate
  • tax_amount to tax.amount
  • is_taxable to tax.is_taxable
  • tax_exempt_amount to tax.tax_exempt_amount
  • tax_metadata to tax.tax_metadata
  • selected_vat_rate_id to tax.vat_rate_id
  • selected_gst_tax_rate_id to tax.gst_tax_rate_id
For native Canada GST and VAT, the first response includes available_rates. Choose one and send it on the next call as selected_vat_rate_id or selected_gst_tax_rate_id. On a record line without auto_calculate_tax, send that rate as tax.vat_rate_id or tax.gst_tax_rate_id. When a write sets auto_calculate_tax to required on a customer transaction, DualEntry reads shipping_address, then billing_address, then the address saved on the customer. If you send neither address, DualEntry copies the customer’s saved address to billing_address and shipping_address. On a vendor record write with auto_calculate_tax set to required, DualEntry reads ship_from_address and ship_to_address, then the addresses saved on the vendor and the company. The write stores only the ship addresses you sent. For a vendor preview on this endpoint, send transaction_ship_from_address and transaction_ship_to_address instead. For US sales tax on this endpoint, send transaction_buyer_address. DualEntry uses that field and does not fall back to the address saved on the customer. This endpoint is part of API v2.

Authorizations

X-API-KEY
string
header
required

Headers

Idempotency-Key
string

Optional. A unique value (a UUID works well) identifying this operation. If the request is repeated with the same key, the original response is replayed instead of the operation running again, so a retry cannot create a duplicate record. Results are replayable for 48 hours. Reusing a key with a different request body returns 422.

Maximum string length: 255

Body

application/json
company_id
integer
required

Company ID

Example:

1

customer_id
integer | null

Customer ID (money-in records)

Example:

1

vendor_id
integer | null

Vendor ID (money-out records)

Example:

null

record_type
enum<string> | null

Optional taxable record type. Customer/vendor credits use ReturnOrder estimates.

Available options:
invoice,
cash_sale,
customer_credit,
sales_order,
bill,
direct_expense,
vendor_credit,
purchase_order
Example:

"invoice"

credit_source
CreditSourceIn · object | null

Optional linked source for customer/vendor credits. Used to pin AvaTax taxOverride.taxDate to the original sale/purchase.

Example:
transaction_buyer_address
TaxLocationIn · object | null

Buyer address on the transaction — required for sales tax, ignored for VAT

Example:
transaction_ship_from_address
TaxLocationIn · object | null

Vendor shipment origin for money-out records. Overrides the vendor default address in tax preview.

transaction_ship_to_address
TaxLocationIn · object | null

Company delivery location for money-out records. Overrides the company default address in tax preview.

transaction_date
string<date> | null

Transaction date — required for sales tax

Example:

"2025-08-29"

supply_date
string<date> | null

Tax point / date of supply — filters VAT and GST rates by valid_from / valid_to

Example:

"2025-08-29"

items
TaxedItemIn · object[]

List of items to calculate tax for

Example:
currency_code
enum<string> | null

Currency code (ISO 4217) — required for sales tax

Available options:
AED,
AFN,
ALL,
AMD,
ANG,
AOA,
ARS,
AUD,
AWG,
AZN,
BAM,
BBD,
BDT,
BGN,
BHD,
BIF,
BMD,
BND,
BOB,
BRL,
BSD,
BTN,
BWP,
BYN,
BZD,
CAD,
CDF,
CHF,
CLF,
CLP,
CNY,
COP,
CRC,
CUP,
CVE,
CZK,
DJF,
DKK,
DOP,
DZD,
EGP,
ERN,
ETB,
EUR,
FJD,
FKP,
GBP,
GEL,
GHS,
GIP,
GMD,
GNF,
GTQ,
GYD,
HKD,
HNL,
HTG,
HUF,
IDR,
ILS,
INR,
IQD,
IRR,
ISK,
JMD,
JOD,
JPY,
KES,
KGS,
KHR,
KMF,
KPW,
KRW,
KWD,
KYD,
KZT,
LAK,
LBP,
LKR,
LRD,
LSL,
LYD,
MAD,
MDL,
MGA,
MKD,
MMK,
MNT,
MOP,
MRU,
MUR,
MVR,
MWK,
MXN,
MYR,
MZN,
NAD,
NGN,
NIO,
NOK,
NPR,
NZD,
OMR,
PAB,
PEN,
PGK,
PHP,
PKR,
PLN,
PYG,
QAR,
RON,
RSD,
RUB,
RWF,
SAR,
SBD,
SCR,
SDG,
SEK,
SGD,
SHP,
SLL,
SOS,
SRD,
STN,
SVC,
SYP,
SZL,
THB,
TJS,
TMT,
TND,
TOP,
TRY,
TTD,
TWD,
TZS,
UAH,
UGX,
USD,
UYU,
UZS,
VES,
VND,
VUV,
WST,
XAF,
XAG,
XAU,
XCD,
XDR,
XOF,
XPD,
XPF,
XPT,
YER,
ZAR,
ZMW,
ZWL
Example:

"USD"

Response

OK

type
enum<string>
required
Available options:
SALES_TAX,
VAT,
GST,
NONE
data
SalesTaxDataOut · object
required