Calculations
A tax calculation quotes the tax for a checkout before you charge the buyer. You display the returned amounts, pass taxCalculationId through your PSP, then commit the transaction after payment succeeds. See Integration for the full sequence.
The response returns aggregate amounts (taxAmount, totalDutyAmount) plus a per-line tax.charges breakdown of every component charged - jurisdiction-level taxes, import duty, and customs fees.
What you pass
- Customer identity and billing address (and shipping address whenever a line item is a physical good)
- Line items with product codes, prices, and quantities
- Product classification per line: productType (DIGITAL or PHYSICAL - pass it explicitly on every line) plus, for physical goods, the product data that drives HS code classification - title, description, category, images, countryOfOrigin, and optionally hsCode
- Ship-from origin address (shipFrom) when physical goods cross a border and import duty should be priced
- Tax identifiers when the jurisdiction requires them (jurisdiction-prefixed types such as EU_VAT)
- Evidence of customer location when required (billing country, IP, payment method country)
Physical goods & customs duties
The API handles two product cases - pass productType explicitly on every line: productType: DIGITAL for digital products and services, productType: PHYSICAL for goods that ship. Any physical line requires customer.shippingAddress because physical-goods tax is destination-based. When the cart also carries shipFrom with an origin country that differs from the destination, Outpost prices import duty for every physical line (the cross-border duty path). Mixed carts are fine - digital lines never carry duty.
HS code classification
- Pass as much product data as you can: title, description, category, images, and countryOfOrigin. The richer the product text, the more accurate the predicted destination-qualified HS code - and therefore the duty and tax rates.
- Already know the code? If you know the full HS code for the destination country, pass it as hsCode (6-14 digits, dots allowed) to skip prediction and optimize classification time - duty is priced directly from your code.
- On the cross-border duty path each PHYSICAL line must carry countryOfOrigin and at least one of title or description; otherwise the calculation is rejected (missing_country_of_origin / missing_classification_text).
- Lines that cannot be classified fall back to a conservative per-destination duty rate; the response marks them dutyBasis FALLBACK_ESTIMATE instead of CLASSIFIED.
Duty and charges in the response
- Import duty is returned per line (tax.dutyAmount, tax.dutyRate, tax.dutyBasis, tax.appliedHsCode) and summed in totalDutyAmount - duty is never folded into taxAmount.
- Duty joins the customs value before VAT: the destination VAT applies to goods + duty, and itemTotalAmount / totalAmount include both tax and duty.
- Each line carries a tax.charges array breaking the totals into components: TAX entries (with jurisdiction, level, and normalized taxType such as VAT, GST, SALES_TAX, IMPORT_VAT) plus IMPORT_DUTY and IMPORT_FEE entries. Use taxAmount and dutyAmount for money flows; the breakdown is for display and reconciliation.
- Physical goods to the US cannot be priced yet - the calculation returns 409 physical_goods_not_supported.
A worked cross-border example (JP → NL: €200 item, €9.00 duty at 4.5%, 21% VAT on goods + duty = €43.89, total €252.89) lives in the API reference.
API map
Request and response schemas live in the API reference - link from here, don't re-implement them on this page.
Region specific
Some jurisdictions add request requirements beyond the common calculation shape. Rules for each region live here - not in the sections above.
Brazil
Brazil NFS-e calculations have stricter request requirements than EU/US quotes. Request and response examples live in the API reference. End-to-end walkthrough: collect payments and stay tax-compliant.
- Currency must be BRL for Brazil NFS-e calculations
- B2C: customer first and last name, plus exactly one BR_CPF tax identifier
- B2B: BR_CNPJ, with buyerTaxRegime (SIMPLES_NACIONAL, LUCRO_PRESUMIDO, or LUCRO_REAL)
- taxBehavior INCLUSIVE - the submitted line amount stays the service value / ISS tax base, and ISS is reported separately, not backed out of the total
- Evidence is optional for Brazil - if provided, billingCountry must be BR
- CPF/CNPJ checks are format and check-digit only - a format-valid ID can still fail at NFS-e issuance
NFS-e vs NFCom: regular (non-telecom) services use NFS-e / ISS. Telecom or communication services (for example eSIM) need NFCom / ICMS instead - do not run them through the NFS-e path.
In sandbox, always send a valid-format BR_CPF or BR_CNPJ. Omitting the identifier can silently return zero tax.