Tax rules define the tax rates applied to charges based on jurisdiction, product category, and customer location. Kontier evaluates tax rules at invoicing time and adds the appropriate tax line items to each invoice.
Key concepts:
- Jurisdiction - country and optional region the rule applies to
- Tax type -
vat,sales_tax,gst,hst, etc. - Inclusive vs. exclusive - whether the tax is included in the listed price or added on top
- Compound tax - whether this tax is calculated on the pre-tax amount or on the amount including other taxes
- Apply order - controls the sequence when multiple tax rules apply
List tax rules
Lists tax rules with cursor-based pagination and the unified field.op=value filter grammar (jurisdiction_country, jurisdiction_region, tax_type, status, rate, valid_from, valid_to, version, created_at, updated_at, published_at, archived_at).
query Parameters
limitPage size. Values above the server-side cap are clamped (standard default 50, cap 200; a few document-heavy lists use larger windows). Invalid values fall back to the default.
cursorOpaque continuation token from the previous response's pagination.cursor. Omit for the first page. Cursors are stateless and do not expire, but are only valid for the list and filters that produced them.
sortOrdering: created_at, with an optional :asc/:desc suffix (default created_at:desc). An unknown value is rejected. Cursors are bound to the ordering that issued them, so changing sort mid-walk needs a fresh first page.
jurisdiction_countryFilter by jurisdiction country (eq/in)
jurisdiction_regionFilter by jurisdiction region (eq/ne/in)
tax_typeFilter by tax type (eq/in)
statusFilter by status (eq/ne/in). Filterable fields accept apifilter operator suffixes, e.g. status__in=A,B
rateFilter by rate (eq/ne/gt/gte/lt/lte)
valid_fromFilter by valid_from (eq/gt/gte/lt/lte)
valid_toFilter by valid_to (eq/gt/gte/lt/lte)
created_atFilter by created_at (eq/gt/gte/lt/lte)
has_scheduled_versionFilter by whether the entity has a version scheduled to publish (true or false). A scheduled version is a FROZEN version row a pending catalog.publish_version Change is bound to; the entity itself stays draft, published or archived and its working draft stays free for immediate changes.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List tax rules › Responses
OK
Create a tax rule
Creates a new tax rule for the organization.
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Create a tax rule › Request Body
jurisdiction_countryrate^-?\d+(\.\d+)?$ · requiredDecimal number encoded as a string to preserve precision.
tax_typeMatched case-insensitively: the server also accepts the all-uppercase and all-lowercase form of each value. The form published here is the canonical one and is what reads back.
valid_fromapplies_to_customer_typesapplies_to_product_categoriesapplies_to_supply_typesapply_orderinclusiveis_compoundjurisdiction_regionrequires_continuous_coveragevalid_toCreate a tax rule › Responses
Created
Get a tax rule
path Parameters
idTax rule UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get a tax rule › Responses
OK
Update a tax rule
Updates an existing tax rule, and publishes nothing. A billing-field edit (rate, jurisdiction, tax type, validity window, applicability) to a LIVE rule STAGES on the draft sibling of its natural key rather than superseding it, so what is being invoiced does not move under the request; a display-only edit (metadata) lands live. Read the staged row with GET /v1/tax-rules/{id}/draft and discard it with DELETE. Taking it live, now or on a date, is POST /v1/changes with operation catalog.publish_version and subject_kind=tax_rule — status="active" here is refused, and there is no effective_at or save_as_draft. valid_from is CONTENT, not a schedule: it says from when the rate applies, and a past one needs acknowledge_retroactive because it rewrites already-invoiced periods.
path Parameters
idTax rule UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Update a tax rule › Request Body
acknowledge_retroactiveRequired to set valid_from in the past. A backdated valid_from rewrites the tax timeline for periods already invoiced — regenerating those invoices will reproduce them at the new rate. Correcting a rate that was always wrong is a legitimate reason to do this; a mistyped date is not, and without this flag the two are indistinguishable.
applies_to_customer_typesapplies_to_product_categoriesapplies_to_supply_typesapply_orderinclusiveis_compoundjurisdiction_countryjurisdiction_regionrate^-?\d+(\.\d+)?$Decimal number encoded as a string to preserve precision.
requires_continuous_coveragetax_typeMatched case-insensitively: the server also accepts the all-uppercase and all-lowercase form of each value. The form published here is the canonical one and is what reads back.
valid_fromvalid_toUpdate a tax rule › Responses
OK
Delete a draft tax rule
Hard-deletes a draft tax rule. Active and archived rules are immutable - use the /archive endpoint instead.
path Parameters
idTax rule UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Delete a draft tax rule › Responses
No Content
Archive a tax rule version
Marks an active tax rule version as archived. Subsequent invoice runs will use the next applicable version (if any).
path Parameters
idTax rule UUID
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Archive a tax rule version › Responses
No Content
Copy a tax rule version as a new draft
Creates a new draft tax rule version seeded from the supplied source version. Use to iterate on rates or jurisdiction logic without disturbing the active version.
path Parameters
idSource tax rule version UUID
Headers
Idempotency-KeyUnique key that makes this POST safe to retry: repeats with the same key replay the first response instead of re-executing. Replays are scoped to the retrying principal (same API key / user) and kept for 24 hours. Required on every POST.
Client-generated idempotency key (e.g. a UUID).
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Copy a tax rule version as a new draft › Request Body
valid_fromvalid_toCopy a tax rule version as a new draft › Responses
Created
Get the staged draft
The entity's open draft: its row id (the same id catalog.publish_version binds as staged_version_id), the version number it will publish as, when it was opened and last touched, the head version it forks from, and a counted summary of what is staged. 404 when nothing is staged — which is a state, not an error.
path Parameters
idThe entity's UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get the staged draft › Responses
OK
Discard the staged draft
Throws the staged draft away. The live entity is untouched: nothing pointed at the draft and it was never on the billing timeline. 404 when nothing is staged, which is a different answer from a successful discard and is reported as one.
path Parameters
idThe entity's UUID
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Discard the staged draft › Responses
No Content
List a tax rule's version timeline
Returns all versions ordered by effective_from. Active and scheduled versions are returned by default; pass include=all to include drafts and archived versions.
path Parameters
idEntity UUID
query Parameters
includeSet to 'all' to include draft and archived versions
limitPage size. Values above the server-side cap are clamped (standard default 50, cap 200; a few document-heavy lists use larger windows). Invalid values fall back to the default.
cursorOpaque continuation token from the previous response's pagination.cursor. Omit for the first page. Cursors are stateless and do not expire, but are only valid for the list and filters that produced them.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List a tax rule's version timeline › Responses
OK
List tax-rule versions (with lifecycle filter)
Returns version rows for the entity, keyset-paginated (default 100, max 200 per page). The status filter accepts draft, scheduled, published, archived; the default excludes draft (ADR-0007). Supports ?include=usage_count and ?archived_reason=.
path Parameters
idEntity UUID
query Parameters
statusLifecycle status filter (repeatable / comma-separated): draft, scheduled, published, archived. Default excludes draft.
archived_reasonNarrow archived rows by reason (repeatable / comma-separated): canceled, discarded, errored, superseded
includeComma-separated includes. Currently supports usage_count.
limitPage size. Values above the server-side cap are clamped (standard default 50, cap 200; a few document-heavy lists use larger windows). Invalid values fall back to the default.
cursorOpaque continuation token from the previous response's pagination.cursor. Omit for the first page. Cursors are stateless and do not expire, but are only valid for the list and filters that produced them.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List tax-rule versions (with lifecycle filter) › Responses
OK
Get a tax-rule version snapshot
Resolves the natural key (country, region, tax_type) from {id} and returns the row whose version matches.
path Parameters
idEntity UUID
versionVersion number
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get a tax-rule version snapshot › Responses
OK
Forecast the impact of superseding this tax-rule version
Who is using the version in force today, and what a publish over it would move. pinnable reports whether holding a version is possible for this entity at all — it is false for tax rules, which are dated rather than pinned, so a caller must not render a pinned count for them. republishes_consumers is the cross-entity fan-out (publishing a price formula republishes every ACTIVE product whose head tiers reference it), and live_readers counts consumers billing off the live head, who move as soon as the publish lands. Read-only, and uncached: this is read at the moment money changes.
path Parameters
idEntity UUID
versionVersion number (positive integer)
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Forecast the impact of superseding this tax-rule version › Responses
OK
List tax-rule version referrers
Offset-paginated drill-down of the referrers of one type for one version of the entity.
path Parameters
idEntity UUID
versionVersion number (positive integer)
query Parameters
typeReferrer type to list (required)
limitPage size. Values above the server-side cap are clamped (standard default 50, cap 200; a few document-heavy lists use larger windows). Invalid values fall back to the default.
cursorOpaque continuation token from the previous response's pagination.cursor. Omit for the first page. Cursors are stateless and do not expire, but are only valid for the list and filters that produced them.
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
List tax-rule version referrers › Responses
OK
Get tax-rule version usage summary
Referrer counts for one version of the entity, grouped by referrer type. Powers the version-switcher hover card.
path Parameters
idEntity UUID
versionVersion number (positive integer)
Headers
X-Workspace-IdSelects the workspace this request operates in, by workspace UUID or slug (e.g. a sandbox workspace for test integrations). Omitted: the organization's default live workspace. Unknown workspace: 404; workspace outside your organization: 403. Discover workspaces via GET /workspaces.
Workspace UUID or slug.
Get tax-rule version usage summary › Responses
OK