Checkout Tax API

Tax for marketplaces, where a Merchant of Record stops working.

One call returns the correct tax rate and whether to charge VAT, apply the B2B reverse charge, or treat the sale as out of scope — with a ready-to-paste invoice note. Built for multi-vendor platforms on Stripe Connect, where every transaction has a different seller country.

Canonical machine spec: /openapi.json (OpenAPI 3.0)

Why it exists

If you sell your own product, a Merchant of Record will swallow this problem for you — use one. It becomes the legal seller and the VAT stops being your concern.

That model breaks the moment your vendors are the real sellers and you only take a cut. An MoR assumes one seller; a marketplace has hundreds, in different countries, each with their own registration status. The calculation lands back on the platform, per transaction. That is who this is for.

The rate depends on where the buyer is, where that seller is, and whether the buyer is a business. Get it wrong and you eat the tax or fail an audit.

Coverage

EU-27 + UK VAT · US state-level sales tax · Canada GST/HST/PST · Australia GST. Rates last reviewed 2026-07.

Authentication

When API_KEYS is configured on the deployment, /rate and /decide require one of:

/health, /openapi.json, and this docs page are always open. RapidAPI proxy may use X-RapidAPI-Proxy-Secret when configured.

API reference

GET /health

Liveness probe. Returns status, version, lastReviewed.

curl "https://checkout-tax-api.pages.dev/health"

GET /openapi.json

OpenAPI 3.0 specification for client generation and marketplace import.

GET /rate

ParameterRequiredDescription
countryyesISO 3166-1 alpha-2 (DE, GB, US, CA, AU, …)
regionUS: yesUS state or CA province code
product_typenodigital (default) or standard

200 response fields: country, countryName, region, regionName, taxType, rate, productType, taxable, notes[], source

curl "https://checkout-tax-api.pages.dev/rate?country=DE&product_type=digital"

POST / GET /decide

FieldRequiredDescription
seller_countryyesSeller establishment (EU-27 or GB in v1)
buyer_countryyesBuyer country
buyer_vat_idnoFormat-checked VAT ID (not VIES-verified)
buyer_regionnoUS state / CA province when applicable
product_typenodigital or standard

200 response fields: chargeVat, mechanism (standard|reverse_charge|zero_rated|out_of_scope), rate, taxType, buyerType, sellerCountry, buyerCountry, vatId, invoiceNote, legalBasis, notes[], disclaimer

curl -X POST "https://checkout-tax-api.pages.dev/decide" \

  -H "Content-Type: application/json" \

  -d '{"seller_country":"DE","buyer_country":"FR","buyer_vat_id":"FRXX123456789"}'

CORS

OPTIONS on any path returns 204 with Access-Control-Allow-Origin: * for browser clients.

Error responses

Errors use shape { "error": { "code": "...", "message": "..." } }:

codeHTTPWhen
missing_country400A `country` (ISO 3166-1 alpha-2) is required.
unsupported_country400Country not in coverage set.
missing_region400US/CA require a `region` (state or province).
unsupported_region400Region not recognized for the country.
missing_seller400`seller_country` is required.
missing_buyer400`buyer_country` is required.
unsupported_seller400Seller must be established in EU-27 or UK (v1).
invalid_json400Request body is not valid JSON.
invalid_product_type400`product_type` must be "digital" or "standard".
method_not_allowed405HTTP method not allowed for this path.
unauthorized401Missing or invalid API key.
not_found404No route for the requested path.

Quick start

JavaScript (fetch)

const res = await fetch("https://checkout-tax-api.pages.dev/decide", {

  method: "POST",

  headers: { "Content-Type": "application/json" },

  body: JSON.stringify({

    seller_country: "DE",

    buyer_country: "FR",

    buyer_vat_id: "FRXX123456789",

  }),

});

const decision = await res.json();

Pricing

Free

$0

Rate lookups + decisions for evaluation and low volume.

Pro

$25/mo

Production volume for a single product.

Ultra

$75/mo

High volume + priority.

Self-host kit

$49

Full source, MIT, 75 tests. Runs on your own Worker, so you pay per invocation instead of a slice of every sale.

Get the source kit →

Download link appears the moment you pay. MIT licensed — no key, nothing phoning home.

Disclaimer

This API provides automated guidance for information only and is not tax or legal advice. VAT numbers are format-checked, not verified as active (use VIES for that). Confirm results with a qualified advisor before invoicing or filing.