What do you want to do?

Register

Register to collect VAT/GST in a new country.

Stay compliant

Track existing registrations, filing calendar, and draft returns.

Classify transactions

Find the right VAT/GST treatment for any transaction.

Monitor exposure

Track sales by country and see where you're approaching a VAT/GST threshold.

Look up a rate

Worldwide VAT/GST/sales tax chart, 153 jurisdictions, 2026. Free reference.

Total Transactions 0
Approved 0
Pending 0
Determinations Today i 0

Determination Volume

Transactions Created

Recent Activity

Timestamp Action User Detail Status
Tax Assistant
Describe transactions or upload a spreadsheet
Template
Hi, I'm the DeterminedAI Tax Assistant. I can help you:

Add transactions, describe them in plain language and I'll classify the VAT/GST treatment
Answer tax questions, ask about rates, rules, registration requirements, or any VAT/GST topic
Analyze a CSV, upload any spreadsheet of transactions and I'll classify them all

Try: "We sell SaaS subscriptions from Germany to businesses in France"
Transaction Code i Description i Category i Supply Type i Confidence i Status i Actions i
Determination ID i Transaction ID i Date Lines Net Total Tax Total Currency Source
Entity Jurisdiction Registration Number Type Effective From Status Actions
Jurisdiction Tax Type Frequency Due Rule Actions

ERP Tax Code Mappings i

Jurisdiction Tax Treatment Supply Type ERP Tax Code Actions
Select Transaction & ERP
No saved transactions? Go to Transactions to set them up first, or select Custom payload to build manually.
POST /v1/tax/determine Header: X-API-Key: your_api_key
Request Payload (editable, modify and click Run)
Response
Select a saved transaction and ERP system, then click "Build & Run" to see the API response.
Quick Start, 3 Steps
1
Get Your API Key

Go to Account and click Generate API Key. Copy it immediately, it's only shown once.

2
Set Up Transactions

Go to Transactions and describe your products/services. Our AI classifies them for tax treatment.

3
Call the API

Send a POST request with your transaction details. We return the tax determination in milliseconds.

Authentication

DeterminedAI accepts two credential types on every data endpoint. Your integrations should use Option A.

Option A, API Key (ERPs, servers, scripts)

Send the key in the X-API-Key header. This is what every ERP connector uses.

curl -X POST https://determinedai.co/v1/tax/determine \
  -H "Content-Type: application/json" \
  -H "X-API-Key: txai_live_your_key_here" \
  -d '{ ... }'
Option B, Supabase JWT (dashboard only)

The dashboard you're looking at uses this path. You do not need to send this from your own code.

Authorization: Bearer <supabase_session_jwt>

Your API key starts with txai_live_. Keep it secret, never ship it in browser JavaScript, mobile apps, or public repos. If it leaks, rotate it immediately.

HTTP Response Codes

Every endpoint returns a standard HTTP status. Use these to decide whether to retry, surface an error, or ask the user to re-authenticate.

Status Meaning Retryable?
200 OK Determination succeeded. Parse line_results[]. -
400 Bad Request Payload failed validation (missing required field, bad ISO country, malformed amount). Response body has details. No, fix the request.
401 Unauthorized No X-API-Key header and no Authorization: Bearer token. You sent a request with no credentials. No, add the header.
403 Forbidden The API key you sent is not recognized, has been revoked, or the Bearer JWT is invalid/expired. Check the key in your ERP plugin matches your dashboard. No, rotate or re-paste the key.
409 Conflict Only on POST /v1/account/api-key: you already have an active key. Use the rotate endpoint to cycle it. No, use rotate.
429 Too Many Requests Monthly plan quota exceeded (500 on Starter, 25k on Professional, 250k on Scale). Response body: "Monthly API quota exceeded (N/M calls)…" No, upgrade plan or wait for next month.
500 Server Error Unexpected error. Capture the response body and contact support with the determination_id if one was returned. Yes, with exponential backoff.
503 Service Unavailable Authentication or account database is temporarily unreachable. This is a transient infrastructure issue, we fail closed rather than silently accept unverified keys. Yes, retry after 1-5s with backoff.

Connector behavior: the NetSuite SuiteScript plug-in will flag the transaction with custbody_taxai_needs_review = true on any non-200 response and optionally apply a zero-rate fallback (if custscript_taxai_fallback is enabled), so bookkeeping is never blocked by an API outage, but the line is queued for human review.

Base URL & Endpoints

Base URL: https://determinedai.co

Method Endpoint Description
POST /v1/tax/determine Raw tax determination, universal format
POST /v1/erp/netsuite/calculate NetSuite SuiteTax native format
POST /v1/erp/xero/calculate Xero accounting format (ACCREC / ACCPAY)
POST /v1/erp/quickbooks/calculate QuickBooks Online format
POST /v1/erp/dynamics365/calculate Dynamics 365 Finance & SCM format
POST /v1/erp/sap/calculate SAP S/4HANA & Business One format
POST /v1/erp/sage-intacct/calculate Sage Intacct format
POST /v1/tax/chat Conversational tax assistant
GET /v1/setup/catalog Retrieve your saved transaction catalog
POST /v1/setup/erp-mapping Create ERP tax code mappings
GET /v1/setup/erp-mapping Retrieve current ERP mappings
GET /v1/setup/erp-mapping/defaults/{erp} Get default mappings for a specific ERP
POST /v1/tax/batch-upload Batch upload transactions (CSV or free-text)
POST /v1/compliance/registrations Add a VAT/GST registration
GET /v1/compliance/registrations List all VAT/GST registrations
POST /v1/compliance/filing-rules Add a filing rule (deadline schedule)
GET /v1/compliance/filing-rules List filing rules and deadlines
GET /v1/account/me Current user, plan, usage, key prefix (Bearer JWT only)
POST /v1/account/api-key Generate a new API key (returned once, store immediately)
POST /v1/account/api-key/rotate Invalidate the current key and issue a new one
Example, Raw API (/v1/tax/determine)

The universal endpoint. Send transaction details and get back the full VAT/GST determination with audit trail.

Request
POST /v1/tax/determine
Content-Type: application/json
X-API-Key: txai_live_your_key

{
  "transaction_id": "INV-2024-001",
  "transaction_type": "sale",
  "transaction_date": "2024-03-15",
  "direction": "AR",
  "seller": {
    "entity_id": "seller-001",
    "name": "Acme SaaS Inc.",
    "country": "US",
    "tax_registrations": [{
      "jurisdiction": "DE",
      "tax_id": "DE123456789",
      "scheme": "VAT"
    }]
  },
  "customer": {
    "customer_id": "cust-42",
    "country": "DE"
  },
  "line_items": [{
    "line_id": "line-1",
    "description": "Cloud SaaS subscription",
    "amount": "99.00",
    "currency": "EUR",
    "product_code": "SAAS-001"
  }]
}
Response
{
  "transaction_id": "INV-2024-001",
  "determination_id": "det_abc123...",
  "timestamp": "2024-03-15T10:30:00Z",
  "line_results": [{
    "line_id": "line-1",
    "supply_type": "electronically_supplied_service",
    "tax_treatment": "standard",
    "rate": 0.19,
    "tax_amount": 18.81,
    "net_amount": 99.00,
    "jurisdiction": "DE",
    "place_of_supply": "DE",
    "gl_tax_code": "VAT-DE-STD-19",
    "confidence_score": 0.97,
    "rule_reference":
      "EU VAT Dir. Art. 58",
    "characterization_reasoning":
      "B2C ESS, tax at customer loc",
    "user_obligation":
      "Charge 19% DE VAT via OSS"
  }],
  "total_tax": 18.81,
  "total_net": 99.00,
  "currency": "EUR",
  "warnings": []
}
Key Request Fields
seller.country (required), ISO 2-letter code customer.country (required), ISO 2-letter code seller.entity_id, .name (required) customer.tax_id (optional), presence = B2B line_items[].description (required), drives AI classification line_items[].incoterm (optional), DDP, FOB, CIF, etc. for goods direction (default: AR), AR (Accounts Receivable) = selling, AP (Accounts Payable) = buying line_items[].product_code (optional), matches catalog for instant lookup
Key Response Fields
rate, decimal (0.19 = 19%), not percentage tax_treatment, standard | reduced | zero_rated | exempt | reverse_charge | outside_scope place_of_supply, where tax is due (ISO country) user_obligation, plain-English action required rule_reference, legal basis (e.g. "EU VAT Dir. Art. 58") gl_tax_code, suggested GL posting code self_assess_rate, for AP reverse charge (buyer self-assesses) erp_tax_code, your ERP-specific tax code (if mappings configured)
ERP-Specific Integrations

Each ERP endpoint accepts payloads in that system's native format, no translation layer needed. Responses include ERP-native tax codes, rule_reference (legal basis for audit defense), and ready-to-post structures.

NetSuite SuiteTax
POST /v1/erp/netsuite/calculate
Required: subsidiary_country, ship_to.country, lines[].item_id, lines[].amount
Optional: entity_tax_id (B2B), incoterm, lines[].item_type (Service, InvtPart)
Returns: tax_details[] with tax_code, tax_rate (%), tax_amount, jurisdiction, rule_reference
Xero
POST /v1/erp/xero/calculate
Required: contact_country, line_items[].description, line_items[].unit_amount
Optional: invoice_type (ACCREC/ACCPAY), contact_tax_number, seller_country (default: GB)
Returns: line_items[] with tax_type (OUTPUT2, ZERORATEDOUTPUT, etc.), rule_reference + ready-to-POST invoice_data
QuickBooks Online
POST /v1/erp/quickbooks/calculate
Required: bill_country, line_items[].amount
Optional: company_country (default: US), customer_tax_id, ship_country, bill_state/ship_state
Returns: line_tax_details[] with tax_code_ref (TAX/NON), rule_reference + ready-to-write txn_tax_detail
Dynamics 365
POST /v1/erp/dynamics365/calculate
Required: company_country, party_country, ship_to.country, lines[].amount
Optional: party_tax_registration, document_type (SalesOrder/PurchaseOrder), party_tax_group
Returns: lines[].tax_components[] with tax_code, tax_rate, jurisdiction, rule_reference + tax_summary[]
SAP S/4HANA & Business One
POST /v1/erp/sap/calculate
Required: company_country, ship_to.country, lines[].line_number, lines[].net_amount
Optional: customer_vat_number, tax_procedure (TAXD, TAXUSJ), source_system (S4HANA/B1), plant
Returns: lines[].conditions[] with condition_type (MWST), tax_rate, jurisdiction_code, rule_reference + bapiret2[] messages
Sage Intacct
POST /v1/erp/sage-intacct/calculate
Required: ship_to_country, lines[].amount
Optional: company_country (default: US), customer_tax_id, tax_solution_id
Returns: tax_entries[] with detail_id, tax_authority, tax_rate (%), tax_amount, taxable_amount, rule_reference
Installing the ERP Plugin, Where to Paste Your Key

Each ERP stores the DeterminedAI API key in its own native secret/config store. You paste it once and the connector sends it on every outgoing call as X-API-Key.

NetSuite (SuiteScript)

Upload TaxAI_SuiteTax_Plugin.js as a SuiteTax Plug-in, then set these script parameters on the deployment record:

custscript_taxai_api_url   = https://determinedai.co
custscript_taxai_api_key   = txai_live_xxxxxxxx...
custscript_taxai_timeout   = 15000
custscript_taxai_fallback  = T  # zero-rate if API down

Full walkthrough: connectors/netsuite/SETUP.md in the integration bundle.

Xero (Python middleware)

Instantiate XeroTaxMiddleware in your backend with the key as a constructor arg, ideally loaded from an env var, never hardcoded:

middleware = XeroTaxMiddleware(
  taxai_api_url=os.environ["TAXAI_API_URL"],
  taxai_api_key=os.environ["TAXAI_API_KEY"],
  xero_client_id=os.environ["XERO_CLIENT_ID"],
  xero_client_secret=os.environ["XERO_CLIENT_SECRET"],
)

Full walkthrough: connectors/xero/SETUP.md.

QuickBooks, D365, SAP, Sage Intacct

These ERPs don't have a drop-in plugin bundle, your backend calls the /v1/erp/<erp>/calculate endpoint directly from whichever webhook or event handler creates invoices/bills in that system. Send the key in X-API-Key:

POST /v1/erp/quickbooks/calculate
X-API-Key: txai_live_xxxxxxxx...
Content-Type: application/json

# See Code Examples below for a full request

Store the key in your backend's secret manager (AWS Secrets Manager, GCP Secret Manager, Vercel environment variables, etc.), never in source control.

Testing the connection

Before wiring up real invoices, smoke-test your key against a simple determination:

curl https://determinedai.co/v1/tax/determine \
  -H "X-API-Key: $TAXAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"transaction_id":"test-1",
       "transaction_type":"sale",
       "direction":"AR",
       "seller":{"entity_id":"s","name":"T","country":"US"},
       "customer":{"country":"DE"},
       "line_items":[{"line_id":"1",
         "description":"SaaS subscription",
         "amount":"99.00","currency":"EUR"}]}'

A 200 with line_results means your key is live. 403 means re-copy the key from the Account page; 503 means retry in a few seconds.

ERP Connector Setup, Step-by-Step Guide

Each ERP speaks a different auth model, a different tax data shape, and a different deployment story. Pick your system from the dropdown to see the step-by-step guide for that integration.

Covers QBO International (UK, CA, AU, IE, ZA, Global) and QBO-US legacy manual sales tax. QBO-US with Automated Sales Tax is detected at initialization and blocked with a clear error so your onboarding flow can stop the integration before persisting tokens.
Supported QBO editions
  • QBO International (UK, CA, AU, IE, ZA, Global), fully supported, manual tax codes
  • QBO-US legacy manual sales tax, supported
  • QBO-US with Automated Sales Tax (AST), not supported. The middleware detects AST at init and raises QBOUnsupportedConfigError; catch this in your onboarding flow and block the integration.
Step 1. Create an Intuit app
  1. Sign in at developer.intuit.com and go to My Apps → Create an app
  2. Pick QuickBooks Online and Payments
  3. Under Scopes, enable com.intuit.quickbooks.accounting
  4. Add your OAuth2 redirect URI and copy your Client ID + Client Secret from Keys & credentials
Step 2. Run the OAuth2 authorization flow

Use Intuit's OAuth 2.0 Playground or your own server to walk the user through authorization. You will end up with four values: realm_id, access_token (~1h), refresh_token (~100d, rotates on use), and expires_in. Persist all four in your secrets store.

Step 3. Install and initialize the middleware
pip install httpx

from qbo_middleware import QBOTaxMiddleware, QBOUnsupportedConfigError

middleware = QBOTaxMiddleware(
    taxai_url="https://determinedai.co",
    taxai_api_key="txai_live_...",
    qbo_client_id="YOUR_INTUIT_CLIENT_ID",
    qbo_client_secret="YOUR_INTUIT_CLIENT_SECRET",
    environment="production",  # or "sandbox"
)

# This probes CompanyInfo + Preferences; raises
# QBOUnsupportedConfigError if the org is QBO-US with AST on.
try:
    await middleware.set_tokens(
        realm_id=stored["realm_id"],
        access_token=stored["access_token"],
        refresh_token=stored["refresh_token"],
        expires_in=stored["expires_in"],
    )
except QBOUnsupportedConfigError as e:
    return error_response(str(e))
Step 4. Create invoices with tax
result = await middleware.create_invoice_with_tax(
    doc_number="INV-2024-042",
    customer_ref="42",
    customer_name="Acme GmbH",
    bill_country="DE",
    customer_tax_id="DE123456789",  # B2B -> EU reverse charge
    currency_code="EUR",
    line_items=[{
        "description": "Cloud analytics - annual SaaS",
        "amount": 1188.00,
        "quantity": 1,
        "item_ref": "SAAS-001",
    }],
)
invoice_id = result["Invoice"]["Id"]
Tax code mapping

QBO TaxCode numeric IDs are company-specific. On set_tokens() the middleware caches the name → id lookup for the org's active tax codes. If your company's tax code names don't match what DeterminedAI returns, configure the mapping via POST /v1/setup/erp-mapping with erp_system: "quickbooks".

Full walkthrough

See connectors/quickbooks/SETUP.md for the complete guide including AST detection internals, error handling, production checklist, and the live sandbox validation notes.

Code Examples
Python
import requests

resp = requests.post(
    "https://determinedai.co/v1/tax/determine",
    headers={
        "X-API-Key": "txai_live_your_key",
        "Content-Type": "application/json",
    },
    json={
        "transaction_id": "INV-001",
        "transaction_type": "sale",
        "direction": "AR",
        "seller": {
            "entity_id": "s1",
            "name": "My Co",
            "country": "US"
        },
        "customer": {"country": "DE"},
        "line_items": [{
            "line_id": "1",
            "description": "SaaS subscription",
            "amount": "99.00",
            "currency": "EUR"
        }]
    }
)
data = resp.json()
line = data["line_results"][0]
print(f"Rate: {line['rate']}")       # 0.19
print(f"Tax:  {line['tax_amount']}") # 18.81
print(f"Code: {line['gl_tax_code']}")# VAT-DE-STD-19
JavaScript / Node.js
const resp = await fetch(
  "https://determinedai.co/v1/tax/determine",
  {
    method: "POST",
    headers: {
      "X-API-Key": "txai_live_your_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      transaction_id: "INV-001",
      transaction_type: "sale",
      direction: "AR",
      seller: {
        entity_id: "s1",
        name: "My Co",
        country: "US",
      },
      customer: { country: "DE" },
      line_items: [{
        line_id: "1",
        description: "SaaS subscription",
        amount: "99.00",
        currency: "EUR",
      }],
    }),
  }
);
const data = await resp.json();
const line = data.line_results[0];
console.log(line.rate);        // 0.19
console.log(line.tax_amount);  // 18.81
console.log(line.gl_tax_code); // VAT-DE-STD-19
Managing Your API Key

Your API key is the identity your ERP, billing platform, or custom backend uses to authenticate with DeterminedAI. Manage it from the Account page or directly via the API.

Generate

Creates your first key. Returns the plaintext exactly once, copy it before closing the dialog.

POST /v1/account/api-key
Authorization: Bearer <session_jwt>

# Response (once, never again)
{
  "api_key": "txai_live_xxxxxxxxxxxxxxxx",
  "prefix":  "xxxxxxxx",
  "message": "Store this key securely..."
}
Rotate (revoke old + issue new)

Use this if your key is compromised, if an employee with key access leaves, or on a scheduled rotation. The old key stops working immediately.

POST /v1/account/api-key/rotate
Authorization: Bearer <session_jwt>

# Response
{
  "api_key": "txai_live_yyyyyyyyyyyyyyyy",
  "prefix":  "yyyyyyyy",
  "message": "Old key has been invalidated..."
}
Key Facts
  • Format: txai_live_ prefix + 32 URL-safe base64 characters. Total length ~42 chars.
  • Storage: we store only a SHA-256 hash, we cannot recover or display your plaintext key after generation. If you lose it, rotate.
  • One active key per account. Calling generate while a key exists returns 409 Conflict; use rotate instead.
  • Identity: the same key works across every ERP connector, the universal /v1/tax/determine endpoint, and any custom scripts. There's no per-ERP key.
  • Dashboard key preview shows only the first 8 characters (e.g. txai_live_aBcDeFgH••••••••). The full key is never re-displayed after generation.
  • Compromised? Rotate immediately. There is no grace period, after rotation, any request with the old key returns 403 Forbidden.
Plans & API Quotas
Plan API Calls / Month ERP Integrations Transactions
Starter (Free) 500 1 ERP 50
Professional ($249/mo) 25,000 2 ERPs Unlimited
Scale ($699/mo) 250,000 All ERPs Unlimited

API calls are counted per /v1/tax/determine (or equivalent ERP endpoint) request. Quotas reset on the 1st of each month UTC. Overage returns 429 Too Many Requests with a message telling you your current count and the plan ceiling, upgrade from the Account page to resume immediately.

Need Help?

Use the Help chat in the bottom-right corner, or reach out via Contact. We're happy to help with your integration.

Non-Union OSS quarterly returns

Manage registrations →

Pick a jurisdiction

Loading jurisdictions…

Free tools

Exposure Check
Free
forever
  • Connect Stripe or upload transactions
  • Countries where you’re required to register for VAT/GST
  • Estimated tax you owe by country
  • Add $29/mo to track your exposure over time
Tax ID Validator
Free
EU, UK, Brazil, Australia + more
  • Single & batch lookups
  • Returns business name + address when the registry offers them
  • No account required

Compliance subscription

One price per jurisdiction, billed monthly. Registration, calculation, monitoring, and filings, all in. EU OSS counts as one jurisdiction (covers all 27 EU countries).

Growth
$79
per jurisdiction / month (10+ jurisdictions)
  • Everything in Starter
  • Volume discount above 10 jurisdictions
  • Priority support
Enterprise
Custom
contact us
  • 50+ jurisdictions, custom mix
  • Dedicated account manager
  • Slack support, custom SLA
  • Custom ERPs and storage
Auto-filed (live): EU OSS, UK, Norway, Australia, New Zealand, Singapore, Canada (federal GST/HST), Ireland, Poland.

Auto-filed (coming soon): Germany, France, Netherlands, Spain.

Pack + filing instructions: Switzerland, Iceland, Korea, Taiwan, Malaysia, Thailand, Turkey, Indonesia, Vietnam, Japan, Philippines.

Already in 5 jurisdictions including the EU? You pay $495/mo total, EU OSS bundled. Contact us to migrate.

Tax Engine only

For teams that handle their own registration and filing in-house and just need VAT/GST calculation on every transaction across 103+ countries. Priced monthly by API volume.

Free
$0
free to start
  • 500 API calls / month
  • 103 countries covered
  • 1 ERP integration
  • AI Tax Assistant
Professional
$249
/ month
  • 25,000 API calls / month
  • 2 ERP integrations
  • Full tax calculation history
  • Email support
Enterprise
Custom
contact us
  • Unlimited API calls
  • Custom ERPs + storage
  • Dedicated support + SLA

Change plan in Account, or contact us for Enterprise.

Non-resident VAT / GST registration

Get registered in any supported jurisdiction. Answer one interview — we prepare the pack; you file it, or we do.

Self-Serve
$199
per regime, one-time
  • Answer a short interview — we fill every field
  • Download your completed registration pack
  • Step-by-step filing instructions included
  • Available for 30+ regimes
Managed available today: EU OSS (One Stop Shop — one registration covers all 27 EU countries), UK, Norway, Australia, New Zealand, Singapore, Canada (federal GST/HST).

Self-Serve only (we prepare, you file): Quebec, British Columbia, Saskatchewan, Manitoba (Canadian provincial tax portals require the business to file directly).
Tax Engine, Subscription
Plan API Calls / Month Transactions ERPs History Support Price
Starter 500 50 1 30 days Community $0 Current
Professional 25,000 Unlimited 2 1 year Email $249/mo
Scale 250,000 Unlimited All Full + export Priority $699/mo
Enterprise Unlimited Unlimited All + custom Full + export Dedicated + SLA Custom Contact
Managed OSS Compliance, We File For You

One-off OSS purchases for customers who don't want the per-jurisdiction Compliance subscription. The subscription includes EU OSS registration and ongoing quarterly filings as a single jurisdiction at $99/month. Your current OSS status: No OSS services purchased.

Service What you get Billing Price
Managed Registration We register your business for Non-Union OSS with Irish Revenue, capture your ROS cert, and include your first quarterly filing. One-time $499
Managed Filing We prepare your quarterly return (automated EU-wide aggregation, ECB FX, Excel workpaper) and our team files it on ROS using your stored Digital Certificate. Amendment support included. Per return $199

Saved snapshots

+ New snapshot

Non-Union OSS

Already registered, or importing an existing OSS registration and ROS cert? Manage it here.

Manage OSS registrations →

Available regimes

Loading regimes…

My registrations

Register a new entity →

New OSS registrations go through the Registrations wizard. Already registered with Revenue? Import your existing one, upload your ROS Digital Certificate and we'll handle quarterly filing.