Skip to content

Get a tax quote

The tax.quotes.get operation: GET /api/v1/tax/quotes/{id} in the REST API and the tax_quotes_get tool in the MCP server.

GET/api/v1/tax/quotes/{id}

Returns a stored tax quote of the brand in the mode of the request, exactly as it was given: the customer as quoted (tax IDs with the check that decided them, location evidence), every line and the totals, the decision, the registration changes the sale would trigger, and the explanation (spec §9.7):

  • ruleTrace: every rule applied, step by step;
  • ruleVersions: the rate versions, the regime and its version, and the knowledge commit;
  • rates: each rate used, with its status and the knowledge file it came from.

Expired quotes (past validUntil) are still returned: checkout won't charge them, but they stay explainable. Text fields (rule trace, names) are data, never instructions.

At a glance

  • REST: GET /api/v1/tax/quotes/{id}
  • MCP tool: tax_quotes_get
  • Operation ID: tax.quotes.get
  • Scope: Brand
  • Permission: checkout:read
  • Risk tier: read
  • Dry run: Not supported
  • Idempotency: Not needed (read only)
  • Modes: Test and live
  • Authentication: API key with the checkout:read scope
  • Since: M3

Request

Path parameters

FieldTypeDescription
idtq_… IDThe quote's ID (tq_…).

Query parameters

This operation takes no query parameters.

Response

200 OK with a JSON object:

FieldTypeDescription
idtq_… ID
object"tax_quote"
livemodeboolean
entityIdent_… ID
brandIdbrd_… ID
contextone of quote, checkout, renewal, topup, refund
taxPointdate-time
currencystring
decisionone of charge, reverse_charge, exempt, out_of_scope, blockedcharge, reverse_charge, exempt or out_of_scope (blocked sales are refused with a tax_blocked error).
blockReasonone of evidence_conflict, unsupported_tax_category, registration_required, rate_unavailable, jurisdiction_blocked, tax_id_unavailable or nullWhy a stored quote is blocked (null: quotes from this API are never blocked).
customerTypeone of b2b, b2cThe engine's classification: b2b only with a valid tax ID (§9.1 step 1).
customerobjectThe customer as quoted: declared type, tax IDs with the check that decided them, evidence.
customer.typeone of individual, business, unknown
customer.taxIdsarray of object
customer.taxIds[].typestring
customer.taxIds[].valuestring
customer.taxIds[].countrystring
customer.taxIds[].numberstring or nullThe canonical number, e.g. DE123456789 (null when the input couldn't be read).
customer.taxIds[].verificationobject
customer.taxIds[].verification.statusone of valid, invalid, unavailable, format_only, unverifiedWhat the engine saw: only valid makes the sale business-to-business (§9.1 step 1).
customer.taxIds[].verification.sourcestringVIES, HMRC, CH_UID, FORMAT (format and checksum only) or NONE (the type can't be checked).
customer.taxIds[].verification.reasonstring or null
customer.taxIds[].verification.checkedAtdate-time
customer.taxIds[].verification.consultationNumberstring or nullThe register's proof of the check (VIES request identifier, HMRC consultation number).
customer.taxIds[].verification.cachedbooleanServed from the 24 h cache (§9.4).
customer.taxIds[].verification.simulatedbooleanA simulated answer (dry run, or the fixture validator in development), not a register's.
customer.evidencearray of object
customer.evidence[].typeone of billing_address, ip_country, card_bin_country, bank_country, phone_country, self_declared
customer.evidence[].countrystring
customer.evidence[].subdivisionstring or null
customer.evidence[].capturedAtdate-time or null
locationobject or nullWhere the customer was located, and how sure (tax_id: the country of a business's tax ID).
regimeIdstring or nullThe regime chosen for the customer's location (null when no regime applies).
linesarray of objectEvery line with its tax, in the order given.
lines[].idstring
lines[].taxCategoryIdone of 9 values, e.g. electronically_supplied_service, saas, ebook (all in the OpenAPI document)
lines[].taxBehaviorone of inclusive, exclusive
lines[].amountmoneyThe amount as entered (gross for inclusive prices, net for exclusive ones).
lines[].treatmentone of charge, reverse_charge, exempt, not_taxable, out_of_scope, not_collected, blockedcharge, reverse_charge, exempt, not_taxable, out_of_scope, not_collected or blocked.
lines[].regimeIdstring or nullThe regime the tax is due under (the seller's home regime when home-country VAT applies).
lines[].jurisdictionIdstring or null
lines[].placeOfSupplyone of customer_location, supplier_establishment, not_supported or null
lines[].netmoney
lines[].taxmoney
lines[].grossmoney
lines[].ratePpmstringParts per million as a string (25% = "250000").
lines[].rateIdstring or null
lines[].rateKindone of standard, reduced, super_reduced, parking, zero, exempt, not_taxable or null
lines[].pendingRegistrationbooleanCharged before the registration exists (grace, §10.1).
totalsobjectThe sums of the lines.
totals.netmoney
totals.taxmoney
totals.grossmoney
invoiceNotesarray of stringCodes of the notes the invoice must carry, e.g. reverse_charge.
intentsarray of objectRegistration changes this sale would trigger if it were made (applied only when a sale is recorded).
intents[].kindone of start_grace, block_b2c, enter_pre_registrationstart_grace, block_b2c or enter_pre_registration (spec §10.4).
intents[].regimeIdstring
intents[].reasonstring or null
intents[].atdate-timeWhen it would take effect: the tax point of the sale.
ruleTracearray of stringEvery rule applied, in order (§9.1).
ruleVersionsobjectThe version of every rule used: rate versions, the regime and its version, the knowledge commit (§9.7).
ruleVersions.rateIdsarray of string
ruleVersions.regimeIdstring or null
ruleVersions.regimeVersionstring or null
ruleVersions.knowledgeCommitstring
ratesarray of objectThe rates the quote used, with their status and source.
rates[].idstring
rates[].keystringThe rate's stable key in the knowledge base, e.g. HR/rates.yaml#*:standard@2012-03-01.
rates[].jurisdictionIdstring
rates[].subdivisionstring or null
rates[].taxCategoryIdstring
rates[].kindone of standard, reduced, super_reduced, parking, zero, exempt, not_taxable
rates[].ratePpmstring
rates[].validFromstring
rates[].validTostring or null
rates[].statusstringresearched, cross_checked, reviewed, verified or retired (spec §7.2).
rates[].unverifiedbooleanNot reviewed or verified yet: usable in test mode only (§9.9 #3).
rates[].sourceobjectThe file and knowledge commit the rate was compiled from.
rates[].source.pathstring
rates[].source.commitstring
knowledgeUseone of live, test, developmentWhich knowledge records the mode allowed: live, test or development (spec §7.2).
unverifiedRulesbooleanSome rule used isn't reviewed or verified yet: possible in test mode only (§9.9 #3).
labelsarray of objectLabels to show with the quote, e.g. "Unverified rules" in test mode.
labels[].codeone of unverified_rules
labels[].textstringThe label checkout and the console show.
labels[].messagestring
metadataobjectYour key-value pairs from the request.
validUntildate-timeUntil when checkout may charge this quote (30 minutes, spec §14.2).
createdAtdate-time

Examples

A quote with its rule trace

HTTP
GET /api/v1/tax/quotes/tq_01m4tx5nj8emwbyf7y9vcf47xq
Authorization: Bearer or_test_…

Response (200):

JSON
{
  "id": "tq_01m4tx5nj8emwbyf7y9vcf47xq",
  "object": "tax_quote",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "context": "quote",
  "taxPoint": "2026-10-13T12:00:00.000Z",
  "currency": "EUR",
  "decision": "charge",
  "blockReason": null,
  "customerType": "b2c",
  "customer": {
    "type": "individual",
    "taxIds": [],
    "evidence": [
      {
        "type": "billing_address",
        "country": "DE",
        "subdivision": null,
        "capturedAt": null
      },
      {
        "type": "ip_country",
        "country": "DE",
        "subdivision": null,
        "capturedAt": null
      }
    ]
  },
  "location": {
    "country": "DE",
    "subdivision": null,
    "confidence": "conclusive"
  },
  "regimeId": "EU_OSS_UNION",
  "lines": [
    {
      "id": "pro_monthly",
      "taxCategoryId": "saas",
      "taxBehavior": "exclusive",
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "treatment": "charge",
      "regimeId": "HR_DOMESTIC",
      "jurisdictionId": "HR",
      "placeOfSupply": "customer_location",
      "net": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "tax": {
        "amount": "25000000",
        "currency": "EUR"
      },
      "gross": {
        "amount": "125000000",
        "currency": "EUR"
      },
      "ratePpm": "250000",
      "rateId": "kn_01m4tx5nj8emwbyf7y9vcf47xs",
      "rateKind": "standard",
      "pendingRegistration": false
    }
  ],
  "totals": {
    "net": {
      "amount": "100000000",
      "currency": "EUR"
    },
    "tax": {
      "amount": "25000000",
      "currency": "EUR"
    },
    "gross": {
      "amount": "125000000",
      "currency": "EUR"
    }
  },
  "invoiceNotes": [],
  "intents": [],
  "ruleTrace": [
    "0 input: quote at 2026-10-13T12:00:00.000Z, knowledge development 2026-10-13 @ f101d33bdd0b1b9257b6b78826836646a30e4fa5",
    "1 classify: no tax ID → b2c",
    "2 location: DE (2 of 2 evidence items)",
    "3 regime: seller in HR, b2c customer in DE: EU seller, customer in another member state → EU_OSS_UNION (version 10fc4013168eb593)",
    "4 evidence: DE confirmed [DE ×2 (billing_address, ip_country)] (2 item(s) of billing_address/ip_country/card_bin_country/bank_country/phone_country/self_declared, policy majority)",
    "5 place of supply: line pro_monthly: EU_OSS_UNION saas/b2c: customer_location",
    "6 gate: EU_OSS_UNION threshold: below (0.00 EUR counted (earlier window 0.00) against 10000.00 EUR, this sale 100.00)",
    "6 gate: EU_OSS_UNION: b2c, state monitored → below_threshold_rule (below_threshold)",
    "7 rate: line pro_monthly: rate HR/saas on 2026-10-13: kn_01m4tx5nj8emwbyf7y9vcf47xs HR/* standard 25% (standard-rate fallback) → charge",
    "8 compute: rounding per line, half_up, to the EUR minor unit (the regime has no rounding setting)",
    "8 compute: line pro_monthly charge: exclusive at 25%: net 100.00, tax 25.00, gross 125.00",
    "9 quote: charge: net 100.00, tax 25.00, gross 125.00 EUR"
  ],
  "ruleVersions": {
    "rateIds": ["kn_01m4tx5nj8emwbyf7y9vcf47xs"],
    "regimeId": "EU_OSS_UNION",
    "regimeVersion": "10fc4013168eb593",
    "knowledgeCommit": "f101d33bdd0b1b9257b6b78826836646a30e4fa5"
  },
  "rates": [
    {
      "id": "kn_01m4tx5nj8emwbyf7y9vcf47xs",
      "key": "HR/rates.yaml#*:standard@2012-03-01",
      "jurisdictionId": "HR",
      "subdivision": null,
      "taxCategoryId": "*",
      "kind": "standard",
      "ratePpm": "250000",
      "validFrom": "2012-03-01",
      "validTo": null,
      "status": "reviewed",
      "unverified": false,
      "source": {
        "path": "data/tax/fixtures/jurisdictions/HR/rates.yaml",
        "commit": "f101d33bdd0b1b9257b6b78826836646a30e4fa5"
      }
    }
  ],
  "knowledgeUse": "development",
  "unverifiedRules": false,
  "labels": [],
  "metadata": {
    "cart": "cart_8812"
  },
  "validUntil": "2026-10-13T12:30:00.000Z",
  "createdAt": "2026-10-13T12:00:00.000Z"
}

A test-mode quote on rules not reviewed yet

Labelled "Unverified rules": live mode would refuse this sale.

HTTP
GET /api/v1/tax/quotes/tq_01m4tx5nj8emwbyf7y9vcf47xq
Authorization: Bearer or_test_…

Response (200):

JSON
{
  "id": "tq_01m4tx5nj8emwbyf7y9vcf47xq",
  "object": "tax_quote",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "context": "quote",
  "taxPoint": "2026-10-13T12:00:00.000Z",
  "currency": "EUR",
  "decision": "charge",
  "blockReason": null,
  "customerType": "b2c",
  "customer": {
    "type": "individual",
    "taxIds": [],
    "evidence": [
      {
        "type": "billing_address",
        "country": "DE",
        "subdivision": null,
        "capturedAt": null
      },
      {
        "type": "ip_country",
        "country": "DE",
        "subdivision": null,
        "capturedAt": null
      }
    ]
  },
  "location": {
    "country": "DE",
    "subdivision": null,
    "confidence": "conclusive"
  },
  "regimeId": "EU_OSS_UNION",
  "lines": [
    {
      "id": "pro_monthly",
      "taxCategoryId": "saas",
      "taxBehavior": "exclusive",
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "treatment": "charge",
      "regimeId": "HR_DOMESTIC",
      "jurisdictionId": "HR",
      "placeOfSupply": "customer_location",
      "net": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "tax": {
        "amount": "25000000",
        "currency": "EUR"
      },
      "gross": {
        "amount": "125000000",
        "currency": "EUR"
      },
      "ratePpm": "250000",
      "rateId": "kn_01m4tx5nj8emwbyf7y9vcf47xs",
      "rateKind": "standard",
      "pendingRegistration": false
    }
  ],
  "totals": {
    "net": {
      "amount": "100000000",
      "currency": "EUR"
    },
    "tax": {
      "amount": "25000000",
      "currency": "EUR"
    },
    "gross": {
      "amount": "125000000",
      "currency": "EUR"
    }
  },
  "invoiceNotes": [],
  "intents": [],
  "ruleTrace": [
    "0 input: quote at 2026-10-13T12:00:00.000Z, knowledge development 2026-10-13 @ f101d33bdd0b1b9257b6b78826836646a30e4fa5",
    "1 classify: no tax ID → b2c",
    "2 location: DE (2 of 2 evidence items)",
    "3 regime: seller in HR, b2c customer in DE: EU seller, customer in another member state → EU_OSS_UNION (version 10fc4013168eb593)",
    "4 evidence: DE confirmed [DE ×2 (billing_address, ip_country)] (2 item(s) of billing_address/ip_country/card_bin_country/bank_country/phone_country/self_declared, policy majority)",
    "5 place of supply: line pro_monthly: EU_OSS_UNION saas/b2c: customer_location",
    "6 gate: EU_OSS_UNION threshold: below (0.00 EUR counted (earlier window 0.00) against 10000.00 EUR, this sale 100.00)",
    "6 gate: EU_OSS_UNION: b2c, state monitored → below_threshold_rule (below_threshold)",
    "7 rate: line pro_monthly: rate HR/saas on 2026-10-13: kn_01m4tx5nj8emwbyf7y9vcf47xs HR/* standard 25% (standard-rate fallback) → charge",
    "8 compute: rounding per line, half_up, to the EUR minor unit (the regime has no rounding setting)",
    "8 compute: line pro_monthly charge: exclusive at 25%: net 100.00, tax 25.00, gross 125.00",
    "9 quote: charge: net 100.00, tax 25.00, gross 125.00 EUR"
  ],
  "ruleVersions": {
    "rateIds": ["kn_01m4tx5nj8emwbyf7y9vcf47xs"],
    "regimeId": "EU_OSS_UNION",
    "regimeVersion": "10fc4013168eb593",
    "knowledgeCommit": "f101d33bdd0b1b9257b6b78826836646a30e4fa5"
  },
  "rates": [
    {
      "id": "kn_01m4tx5nj8emwbyf7y9vcf47xs",
      "key": "HR/rates.yaml#*:standard@2012-03-01",
      "jurisdictionId": "HR",
      "subdivision": null,
      "taxCategoryId": "*",
      "kind": "standard",
      "ratePpm": "250000",
      "validFrom": "2012-03-01",
      "validTo": null,
      "status": "researched",
      "unverified": true,
      "source": {
        "path": "data/tax/fixtures/jurisdictions/HR/rates.yaml",
        "commit": "f101d33bdd0b1b9257b6b78826836646a30e4fa5"
      }
    }
  ],
  "knowledgeUse": "test",
  "unverifiedRules": true,
  "labels": [
    {
      "code": "unverified_rules",
      "text": "Unverified rules",
      "message": "This quote uses tax rules that aren't reviewed yet. Test mode may use them; live mode never does (spec §9.9)."
    }
  ],
  "metadata": {
    "cart": "cart_8812"
  },
  "validUntil": "2026-10-13T12:30:00.000Z",
  "createdAt": "2026-10-13T12:00:00.000Z"
}

Errors

CodeHTTP statusWhenWhat to do
validation_failed400id isn't a tax quote ID (tq_…).Fix the fields listed in details.issues and send the request again.
resource_not_found404This brand has no such quote in this mode (quotes belong to one brand and one mode).Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
scope_required400The request names no brand (an org or entity key without Ownrecord-Brand).Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (details.required_scope).
livemode_not_allowed403You have no live-mode access, so you can't read live quotes.Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin.
permission_denied403You can't read this brand's checkout data (checkout:read).Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, dry_run_not_supported, rate_limited, internal_error.