> ## Documentation Index
> Fetch the complete documentation index at: https://zenskar.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tax configuration

<Info>
  **Availability**: The Tax Configuration tab is rolled out to organizations using Zenskar's contract-based billing. If you do not see this tab under **Settings**, contact your Zenskar account team.
</Info>

## 1. Concepts: How tax configuration works in Zenskar

**Settings > Tax Configuration** is where you tell Zenskar what gets taxed, where each of your business entities does business, and how tax should be calculated in each of those places. It has two levels:

* An **organization level** (the main Tax Configuration page) where you maintain a shared catalog of **tax categories**.
* A **business entity level** (reached by clicking **Configure** on an entity) where you set up the **countries that entity serves** and, for any country where Zenskar calculates tax itself, the actual **tax rates**.

### Tax categories

A tax category is a reusable label for "what kind of thing is being taxed," for example *GST - Software Services*, *Sales Tax*, or *VAT - Digital Goods*. Categories are shared across your entire organization: you define them once, then reference the same category from tax rates in any business entity, and from products.

Every category gets a system-generated code (`ZEN_TAX_00001`, `ZEN_TAX_00002`, and so on) that never changes. You control the display name.

If you have connected **Avalara** or **Anrok** as a tax integration, each category can also carry that provider's code (an Avalara Tax Code or an Anrok Item Code), so the mapping between how Zenskar classifies this and how the provider classifies this lives in one place. Without a connected provider, this mapping is hidden, since there is nothing to map to yet.

### Countries serving, currencies, and tax engines

For each business entity, **Countries Serving** is the list of countries you bill customers in. For every country you add, you choose:

* Which **currencies** you bill in for that country (a country can have more than one).
* Which **tax engine** calculates tax there: **Zenskar**, **Avalara**, or **Anrok**.

The tax engine choice matters per country, not globally: one entity could use Zenskar's own rates for India while delegating tax in the UK to Avalara.

* **Zenskar** as the engine means you configure your own jurisdiction-based tax rates (below), and Zenskar computes tax from them at invoice time.
* **Avalara** or **Anrok** means Zenskar calls out to that connected provider at invoice time, and the provider returns the tax to apply. You do not maintain rates in Zenskar for that country.

<Warning>
  Disabling a currency for a country blocks new invoice generation for contracts billed in that currency going forward. Existing invoices already generated are not affected. Switching a country's tax engine only changes how future invoices are taxed. Past invoices are unaffected, and if you switch away from Zenskar and back again, your previously configured Zenskar rates are still there and reactivate.
</Warning>

### Zenskar tax rates and jurisdictions

When a country's tax engine is **Zenskar**, you configure the actual rates yourself, per **tax category**, at a level of geographic detail you choose:

* Country (required)
* State (optional)
* City (optional, requires a state)
* ZIP/postal code range (optional, requires a state and city)

Each jurisdiction/category combination holds one or more **rate components**: a name (for example `CGST`) and a percentage (for example `9%`). A single jurisdiction commonly needs more than one component (for instance `CGST: 9%` plus `SGST: 9%` for an Indian state); Zenskar adds them together (rate stacking is additive today).

**Matching a customer to a rate.** At invoice time, Zenskar looks for the most specific rate that matches the customer's billing destination, checking ZIP, then city, then state, then country, and stopping at the first level with a configured rate. In practice this means:

* A country-level rate acts as the default for every customer in that country.
* Adding a more specific state, city, or ZIP-level rate for the same category overrides the country-level default for just that location. The country-level rate still covers everyone else.

```mermaid theme={null}
flowchart TD
    A["Customer's billing destination
    e.g. Country + State + City"] --> B{"Rate at ZIP level?"}
    B -- Yes --> R["Apply that rate"]
    B -- No --> C{"Rate at City level?"}
    C -- Yes --> R
    C -- No --> D{"Rate at State level?"}
    D -- Yes --> R
    D -- No --> E{"Rate at Country level?"}
    E -- Yes --> R
    E -- No --> F["No match:
    invoice/contract activation is blocked"]
```

<Note>
  This walk only moves toward the country level, never the other way. A rate you have scoped to a specific state only applies to customers whose destination is known down to that state. It does not retroactively apply just because a customer happens to be in that state if Zenskar was not given that level of detail to match against.
</Note>

**Effective dating.** Each rate carries an effective-from date, and you can schedule a **future rate change** for the same jurisdiction and category ahead of time. Zenskar shows it as **Scheduled** until it takes effect, then **Active**, then **Expired** once superseded. Two schedules for the same jurisdiction and category cannot share an effective date, and their date ranges cannot overlap or touch. Each new schedule effectively closes out the one before it.

**No silent zero-tax.** If a country's tax engine is Zenskar and no rate covers a customer's destination (or a jurisdiction exists but has no active rate components), Zenskar does not charge 0% by default. It blocks invoice or contract activation until you add the missing coverage. This fail-closed behavior does not apply when the engine is Avalara or Anrok, since those providers resolve the rate themselves.

### How this relates to other tax-adjacent settings

* **Business Entity > Tax Information** (VAT ID / PAN / GSTIN / Tax ID) is a separate, simpler feature: it records your own entity's tax registration numbers for compliance recordkeeping. It does not drive tax calculation. That is what Tax Configuration is for. See [Business entity](/docs/20260301/product-modules/settings/business-entity).
* **Products** can be tagged with a tax category. Zenskar shows the assigned category on the product as a link back to this page (along with its mapped Avalara code, if one is set). The actual rate applied on an invoice is resolved from the customer's destination, business entity, and effective date, not fixed on the product itself.

***

## 2. Walkthrough: Set up Zenskar-calculated tax for a country

This walkthrough sets up native (non-connector) tax for a business entity serving India, using a two-component GST rate (CGST + SGST) as the example, then schedules a future rate change.

1. Go to **Settings > Tax Configuration**.
2. On the **Tax Categories** tab, click **Add Tax Category**.
   * **Name**: `GST - Software Services`.
   * Leave the Avalara/Anrok code fields alone unless you have connected one of those providers and want to map this category to a provider tax code.
   * Click **Save**. Zenskar assigns it a code like `ZEN_TAX_00001`.
3. Switch to the **Entities** tab and click **Configure** on the business entity you want to set up.
4. On the entity's **Countries Serving** tab, click to add a country:
   * **Country**: India.
   * **Currencies**: select `INR`.
   * **Tax Engine**: Zenskar.
   * Save. India now appears in the Countries Serving table with the Zenskar badge.
5. Switch to the entity's **Tax Rates** tab and click **Add Tax Rate**.
   * **Tax Category**: `GST - Software Services`.
   * **Where this rate applies**: Country = India. Leave State/City/ZIP unset for a country-wide rate.
   * Under **Tax Rate**, set the **Effective From** date and add two components: `CGST` at `9%` and `SGST` at `9%`.
   * Click **Save**. The rate shows as **Active** (or **Scheduled**, if the effective date is in the future).
6. To see scheduling in action, open the same rate again and click **Schedule Rate Change**. Give the new schedule a later **Effective From** date and a different rate (for example `CGST: 9.5%`, `SGST: 9.5%`). Save.
   * The rates table now shows an **{n} rate changes** link on that jurisdiction row. Clicking it opens a read-only history showing the current schedule as **Active** and the new one as **Scheduled**, with the boundary between them handled automatically.

From here, any invoice generated for a customer under this business entity, billed in INR, with a destination in India, picks up the active GST rate for that date automatically.

***

## 3. How-to guides

### Manage tax categories

* **Create a category**: **Settings > Tax Configuration > Tax Categories > Add Tax Category**. Enter a **Name** (required); the **Code** is generated automatically and cannot be changed.
* **Map a category to Avalara or Anrok**: open the category and fill in the **Avalara Tax Code** and/or **Anrok Item Code** fields. These only appear once the corresponding connector is configured under Integrations. If neither is connected, use the **Connect tax tools** link shown in the panel instead.
* **Rename a category or edit its provider mapping**: click the category's row to reopen the same panel. The category's **Code** is permanent; only the name and provider mapping can change.

<Info>
  There is no delete action for tax categories. A category can be renamed or have its provider mapping cleared, but not removed, since products and rates may still reference it.
</Info>

### Manage countries a business entity serves

* **Add a country**: on the entity's **Countries Serving** tab, add a country, choose one or more currencies, and pick a tax engine (Zenskar/Avalara/Anrok).
* **Add or remove a currency for an existing country**: edit the country row. Toggling a currency off keeps its history but blocks new invoices in that currency; at least one currency must stay enabled.
* **Change the tax engine for a country**: edit the country row and change **Tax Engine**. This affects future invoices only.
* **Remove a country entirely**: use the row menu's **Remove** option. This removes all currencies configured for that country in one action.

### Manage Zenskar tax rates

* **Add a rate for a country**: on the entity's **Tax Rates** tab, click **Add Tax Rate**, pick the **Tax Category**, set **Country**, and add one or more **{name, percentage}** components effective from a date.

  <Info>
    You can only pick from countries already added under **Countries Serving** for that entity. Add the country first if it is not in the dropdown.
  </Info>
* **Add a state/city/ZIP-level override**: in the same panel, use **+ Add State**, then **+ Add City**, then **+ Add ZIP Code** to narrow the jurisdiction. Each level requires the one above it to be filled in first (a ZIP needs a city and state; a city needs a state). For a single ZIP code rather than a range, enter the same value for the start and end.
* **Schedule a future rate change**: open an existing rate (or add a new one) and click **Schedule Rate Change** to add another effective-dated set of components. Status pills show **Active**, **Scheduled**, and **Expired** schedules on the same jurisdiction.
* **Review a jurisdiction's full rate history**: click the **{n} rate changes** link on a jurisdiction row in the rates table to open a read-only view of every schedule, its date range, and its components.

### Troubleshooting

* **"Overlapping rate window" or similar conflict when saving a schedule**: two schedules on the same jurisdiction and category cannot share a start date, and one schedule's range cannot overlap, or touch on the same day, another active one. Adjust the new **Effective From** date so it starts the day after the previous schedule ends, or after its start date if it is open-ended.
* **"Saved {n} of {total} rate changes"**: if you added several schedules to one rate at once and one of them failed validation, the ones that succeeded are kept. Only the failed schedule(s) remain in the form for you to fix and resubmit.
* **Cannot select a country in Add Tax Rate**: the country needs to be added under **Countries Serving** on that entity first.
* **Invoice or contract activation blocked citing missing tax coverage**: the customer's destination (or the effective date) is not covered by any active Zenskar rate for the relevant category. Add a rate for that country (or the more specific state/city/ZIP) that covers the date in question, or switch that country's tax engine to a connected provider.

***

## 4. Reference

### Location

**Settings > Tax Configuration** (organization level), then **Configure** on a business entity, then the entity-level page with **Countries Serving** and **Tax Rates** tabs.

### Data model

**Tax category**

| Field            | Description                                                                                                          |
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| `code`           | System-generated, permanent (for example `ZEN_TAX_00001`)                                                            |
| `name`           | Display name, 1-255 characters, unique within your organization                                                      |
| `external_codes` | Provider code mapping (for example Avalara Tax Code, Anrok Item Code); only editable when that provider is connected |

**Country / currency configuration ("Countries Serving" row)**

| Field                    | Description                                                             |
| ------------------------ | ----------------------------------------------------------------------- |
| `country_code`           | ISO country code                                                        |
| `currency_code`          | ISO currency code; a country can have multiple rows, one per currency   |
| `is_enabled`             | Whether new invoices can be generated in this currency for this country |
| `tax_calculation_method` | `Zenskar`, `Avalara`, or `Anrok`                                        |

**Tax rate jurisdiction**

| Field                             | Description                                                                                            |
| --------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `tax_category_id`                 | The tax category this rate belongs to (required)                                                       |
| `country_code`                    | Required, ISO country code                                                                             |
| `state_code`                      | Optional, up to 10 characters                                                                          |
| `city`                            | Optional, up to 100 characters; requires `state_code`                                                  |
| `zip_code_start` / `zip_code_end` | Optional, up to 20 characters each; both required together, end must be greater than or equal to start |
| `effective_from` / `effective_to` | The schedule's active window; `effective_to` is open-ended (null) until a later schedule supersedes it |
| `is_active`                       | Manually deactivating a schedule marks it **Expired** even if today falls inside its date range        |

**Rate component**

| Field          | Description                                                          |
| -------------- | -------------------------------------------------------------------- |
| `tax_name`     | 1-50 characters, unique within its jurisdiction (for example `CGST`) |
| `rate_percent` | 0-100, up to 2 decimal places                                        |

### Rate status

| Status    | Meaning                                                                                     |
| --------- | ------------------------------------------------------------------------------------------- |
| Active    | Today falls within the schedule's effective window and it has not been manually deactivated |
| Scheduled | The schedule's `effective_from` date is in the future                                       |
| Expired   | The schedule's window has ended, or it was manually deactivated                             |

### Validation rules

| Rule                                                                                                       | Effect                                                                    |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Tax category name must be unique per organization                                                          | Duplicate names are rejected                                              |
| A city requires a state; a ZIP range requires a city and state                                             | Rejected if a more specific field is set without the levels above it      |
| ZIP range end must be greater than or equal to start                                                       | Rejected otherwise                                                        |
| Two schedules on the same jurisdiction and category cannot share an effective-from date                    | Rejected                                                                  |
| Two active schedules on the same jurisdiction and category cannot have overlapping or touching date ranges | Rejected. Close out the earlier schedule before the new one starts        |
| Two rate components in the same schedule cannot share a name                                               | Rejected                                                                  |
| Rate percentage must be between 0 and 100                                                                  | Rejected otherwise                                                        |
| Concurrent edits to the same rate                                                                          | The second save is rejected as a conflict; reload and reapply your change |

### API reference

Programmatic access to tax categories and jurisdiction rates. All endpoints require an API key with organization read access; write operations additionally require permission to update organization configuration.

| Method   | Endpoint                                                                                                                  |
| -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | [List tax categories](/docs/api-reference/tax/list-tax-categories)                                                             |
| `POST`   | [Create tax category](/docs/api-reference/tax/create-tax-category)                                                             |
| `GET`    | [Get tax category](/docs/api-reference/tax/get-tax-category)                                                                   |
| `PATCH`  | [Update tax category](/docs/api-reference/tax/update-tax-category)                                                             |
| `GET`    | [List jurisdiction rates](/docs/api-reference/tax/list-jurisdiction-rates)                                                     |
| `POST`   | [Create jurisdiction rate](/docs/api-reference/tax/create-jurisdiction-rate)                                                   |
| `GET`    | [Get jurisdiction rate](/docs/api-reference/tax/get-jurisdiction-rate)                                                         |
| `PATCH`  | [Update jurisdiction rate](/docs/api-reference/tax/update-jurisdiction-rate)                                                   |
| `GET`    | [List tax rates](/docs/api-reference/tax/list-tax-rates)                                                                       |
| `GET`    | [Get tax rate](/docs/api-reference/tax/get-tax-rate)                                                                           |
| `PATCH`  | [Update tax rate](/docs/api-reference/tax/update-tax-rate)                                                                     |
| `POST`   | [Resolve the applicable tax rate for a destination](/docs/api-reference/tax/resolve-the-applicable-tax-rate-for-a-destination) |
| `GET`    | [Get business entity config](/docs/api-reference/business-entities/get-business-entity-config)                                 |
| `PUT`    | [Set business entity config](/docs/api-reference/business-entities/set-business-entity-config)                                 |
| `GET`    | [Get region config](/docs/api-reference/business-entities/get-region-config)                                                   |
| `PUT`    | [Upsert region config](/docs/api-reference/business-entities/upsert-region-config)                                             |
| `DELETE` | [Delete region config](/docs/api-reference/business-entities/delete-region-config)                                             |

<Info>
  New tax rate components can only be added as part of creating a jurisdiction rate. To add a component to an existing jurisdiction, create a new scheduled rate change through the UI rather than through a standalone API call. There is no dedicated "add rate" endpoint separate from jurisdiction rate creation.
</Info>
