---
title: Managed mode for Shopify Tax - Shopify developer changelog
description: >-
  Shopify’s developer changelog documents all changes to Shopify’s platform.
  Find the latest news and learn about new platform opportunities.
source_url:
  html: 'https://shopify.dev/changelog/posts/managed-mode-for-shopify-tax-is-released'
  md: >-
    https://shopify.dev/changelog/posts/managed-mode-for-shopify-tax-is-released.md
metadata:
  effectiveApiVersion: 2027-01
  affectedApi:
    - displayName: Admin REST API
      handle: admin-rest
    - displayName: GraphQL Admin API
      handle: admin-graphql
  primaryTag:
    displayName: API
    handle: api
  secondaryTag:
    displayName: Breaking API Change
    handle: breaking-api-change
  indicatesActionRequired: true
  createdAt: '2026-10-19T15:14:22-04:00'
  postedAt: '2026-10-28T11:50:00-04:00'
  updatedAt: '2026-10-27T12:58:23-04:00'
  effectiveAt: '2026-10-22T00:00:00-04:00'
---

October 28, 2026

# Managed mode for Shopify Tax

DateOctober 28, 2026

Version[2027-01](https://shopify.dev/changelog?api_version=2027-01)

Flags[Breaking API Change](https://shopify.dev/changelog?filter=breaking-api-change)[Action required](https://shopify.dev/changelog?action_required=true)

SurfacesAPI

Affected APIs[Admin REST API](https://shopify.dev/changelog?api_type=admin-rest)[GraphQL Admin API](https://shopify.dev/changelog?api_type=admin-graphql)

Shopify Tax managed mode helps Shopify apply the correct tax behavior for US sales by managing some store settings and API behavior directly. To keep those settings consistent, some Admin API writes now validate against the requirements of managed mode.

Managed mode sets requirements that Shopify uses to keep tax behavior consistent across a store. In some cases, the API now prevents apps from writing settings that would conflict with those requirements. In other cases, tax behavior now depends on more specific product or store data instead of simple boolean settings.

For app developers, the main pattern is:

* Requests that already use the required settings, or that omit settings the app doesn't need to manage, continue to work.
* Requests that try to override managed-mode requirements might now return validation errors.

These changes affect apps that configure markets, publish products, create custom line items, or preview checkout branding for stores that use Shopify Tax managed mode. The changes fall into four categories:

* **Breaking changes:** Markets API writes and product publishing writes can now fail when they conflict with Shopify Tax managed mode requirements.
* **Deprecation:** The `taxable` input on custom line items is deprecated in favor of `productCategoryId`.
* **New capability:** Apps can assign product categories to custom line items in draft orders and order edits.
* **Behavior clarification:** Checkout footer visibility controls merchant-configurable content only, not Shopify-provided transaction information.

## Breaking: Markets API writes require fixed US defaults

For stores that use Shopify Tax in managed mode for US sales, the [`marketCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/marketCreate) and [`marketUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/marketUpdate) mutations now reject attempts to override required currency and tax-display defaults for affected markets. The validation applies only to merchant-managed, non-retail markets that include the United States. Markets without the United States, retail markets, and third-party-managed markets are excluded.

Stores that don't use Shopify Tax managed mode are unaffected even if they sell to US customers.

### Affected requests

This change applies across all supported API versions, including `unstable`. The validation only applies when a request supplies `currencySettings` or `priceInclusions`, so requests that omit these inputs are unchanged. When one of these inputs is submitted, Shopify validates the resulting setting, including retained values and defaults for omitted subfields.

If your app sets these fields, use the required defaults or omit fields that your app doesn't need to manage.

For a US-only market, the following optional inputs use the required defaults:

```
{
  "currencySettings": {
    "baseCurrency": "USD",
    "localCurrencies": false
  },
  "priceInclusions": {
    "taxPricingStrategy": "ADD_TAXES_AT_CHECKOUT"
  }
}
```

For a market that includes the United States and another country, such as Canada, the following optional inputs use the required defaults:

```
{
  "currencySettings": {
    "localCurrencies": true
  },
  "priceInclusions": {
    "taxPricingStrategy": "INCLUDES_TAXES_IN_PRICE_BASED_ON_COUNTRY"
  }
}
```

Handle validation errors through `userErrors.code`, `userErrors.field`, and `userErrors.message`. Currency violations return `UNSUPPORTED_CURRENCY`. Tax-display violations return `INCOMPATIBLE_CONFIGURATION` on API version `2026-07` and later, or `GENERIC_ERROR` on earlier versions.

### Related docs

* [Market currency settings input](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/MarketCurrencySettingsUpdateInput)
* [Market price inclusions input](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/MarketPriceInclusionsInput)
* [Market mutation error codes](https://shopify.dev/docs/api/admin-graphql/latest/enums/MarketUserErrorCode)

## Breaking: Product publishing requires the Shop channel

For stores that use Shopify Tax managed mode, products published to Online Store, Headless, Hydrogen, or Buy Button must also be published to Shop. These channels depend on Shop, so requests that would leave a product on one of these channels without Shop are handled differently by API version. In `unstable`, the request fails. In dated versions, Shopify adds the missing Shop or dependent-channel changes to the request and saves it. Shopify doesn't save any part of a failed request.

The failures described below apply to the `unstable` API version. Dated versions apply the same rules, but change the request instead of failing it. Refer to [Dated API versions](#dated-api-versions). Stores that don't use Shopify Tax managed mode are unaffected, and requests that only change other sales channels, collections, or product variants are unchanged. The change is rolling out gradually to stores that use managed mode, with no schema changes.

### Affected requests

A product counts as being on a channel when it's published there, scheduled to publish there, or, for draft products, added to that channel. A request that includes both Shop and a dependent channel is checked as a whole, in any order.

The validation applies to `publishablePublish`, `publishableUnpublish`, and `publicationUpdate`. It also applies to deprecated GraphQL publishing APIs, including `productPublish`, `productUnpublish`, and the publishing fields on `productCreate` and `productUpdate`. For the REST Admin API, product create and update requests fail when they would put a product on Online Store while the product isn't on Shop or is blocked by Shop.

Additional validation rules apply:

* Shop blocks a product when it rejects the product or flags it as needing action. `publishablePublish` fails if Shop blocks the product and the resulting state leaves it on a dependent channel, even if the request publishes only to Shop. `productUpdate` also fails if Shop blocks the product and the resulting state leaves it on a dependent channel.

* Removing a product from Shop requires removing its dependent-channel publications, in any state. This applies to `publishableUnpublish` and to `publicationUpdate` removals from Shop.

* For `publicationUpdate`:

  * Adding a product to a dependent channel fails if the product isn’t on Shop or Shop blocks it. Adding a blocked product to Shop also fails if it remains on a dependent channel. Products already in the target publication aren’t checked when included in `publishablesToAdd`.
  * `publicationUpdate` rejects `autoPublish`: true on a dependent channel when Shop’s publication doesn’t auto-publish. It also rejects `autoPublish`: false on Shop when a dependent channel still auto-publishes.

* On `productUpdate`, publications replace the product’s entire publication list. Include Shop whenever the replacement list includes a dependent channel, even if the product is already on Shop. When the request also changes status, validation uses the new status.

The deprecated `productPublish` and `productUnpublish` mutations follow the same failure conditions as `publishablePublish` and `publishableUnpublish`.

### Dated API versions

On dated API versions, Shopify changes a request that breaks these rules so that it follows them, then saves it:

* Publishing a product to a dependent channel also publishes it to Shop. Shop doesn't support scheduled publishing, so Shopify publishes to Shop immediately, even when the dependent channel is scheduled.
* Removing a product from Shop also removes it from its dependent channels.
* On `productCreate` and `productUpdate`, including the product-level publishing fields, Shop is added when the request puts the product on Online Store or another dependent channel. On `productUpdate`, a publications list that leaves out Shop keeps the product on Shop.
* For `publicationUpdate`, adding products to a dependent channel also adds them to Shop, and removing products from Shop also removes them from dependent channels. Turning on `autoPublish` for a dependent channel also turns it on for Shop. Turning off `autoPublish` for Shop also turns it off for dependent channels.
* A Shop rejection or a "needs action" flag doesn't block the request.
* REST Admin API product, product listing, and product publication requests behave the same way.

If the request still breaks the rules after these changes, it fails with the same error as in `unstable`. For example, this happens when a draft product is scheduled on a dependent channel without Shop.

Keep in mind:

* If your app publishes products to Online Store, Headless, Hydrogen, or Buy Button, publish the product to Shop first or include Shop in the same request. If your app unpublishes a product from Shop, unpublish it from dependent channels first or include those removals in the same request.
* If your app creates active products with the REST Admin API, send `"published": false`, then publish the product to Shop and Online Store with `publishablePublish`.
* On dated versions, Shopify can publish a product to Shop, or remove it from dependent channels, even when your request didn't name those channels. To control the result, send Shop and its dependent channels together.

Handle these failures as validation errors. Retrying the same request returns the same error. Publishing requests fail with `For the store setup, Shop publication is a prerequisite`. Unpublishing requests fail with `For the store setup, unpublishing from dependent publications is a prerequisite`.

### Related docs

* [`publishablePublish`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/publishablePublish)
* [`publishableUnpublish`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/publishableUnpublish)
* [`publicationUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/publicationUpdate)
* [REST Admin API: Product](https://shopify.dev/docs/api/admin-rest/latest/resources/product)

## Deprecated: `taxable` on custom line items

The [`taxable`](https://shopify.dev/docs/api/admin-graphql/2027-01/input-objects/DraftOrderLineItemInput#fields-taxable) input for custom line items in draft orders and order edits is deprecated in favor of `productCategoryId`, which assigns a category from Shopify's Standard Product Taxonomy and lets Shopify determine the item's tax treatment.

On GraphQL Admin API version `2027-01` and later, `DraftOrderLineItemInput.taxable` and the `taxable` argument on `orderEditAddCustomItem` are marked as deprecated. Apps on API version `2026-10` or earlier don't see a schema change.

* Reading the `taxable` state isn't deprecated, so fields that return whether a line item is taxable, and webhook payloads that include taxable state, are unchanged.
* For stores using Shopify Tax managed mode, `taxable` is ignored on custom line items in every API version. The product category sets tax treatment, and a custom line item with no category is taxed at the standard rate. For all other stores, `taxable` works as before.

If your app sets `taxable` when creating or editing custom line items, replace it with `productCategoryId` on GraphQL Admin API version `2027-01` or later. To exempt an entire draft order on a store that uses Shopify Tax managed mode, mark the customer, company, or company location as tax-exempt. Use a category to exempt a single item.

### Related docs

* [`DraftOrderLineItemInput`](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/DraftOrderLineItemInput)
* [`orderEditAddCustomItem`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/orderEditAddCustomItem)
* [REST Admin API: DraftOrder](https://shopify.dev/docs/api/admin-rest/latest/resources/draftorder)

## New: Set product categories on custom line items in draft orders and order edits

You can now assign a category from Shopify's Standard Product Taxonomy to custom line items in draft orders and order edits. The category controls the item's tax treatment in the same way it does for products.

For stores using Shopify Tax managed mode, `productCategoryId` is the input that sets a custom line item's tax treatment. The `taxable` input is ignored. A custom line item with no category is treated as Uncategorized and taxed at the standard rate.

For stores that don't use Shopify Tax managed mode, `taxable: false` continues to mean that the custom line item isn't taxed. When the item is taxed, Shopify can use its category to calculate tax.

### Affected requests

In draft orders, `DraftOrderLineItemInput.productCategoryId` sets the product category for a custom line item in `draftOrderCreate`, `draftOrderUpdate`, and `draftOrderCalculate`. It's ignored when `variantId` is provided. You can read the saved category from `DraftOrderLineItem.productCategory` and `CalculatedDraftOrderLineItem.productCategory`; these fields return `null` for product variant line items.

In order edits, `orderEditAddCustomItem` accepts a new `productCategoryId` argument. You can read the category from `CalculatedLineItem.productCategory`.

If `productCategoryId` doesn't match a category in the current taxonomy, the mutation returns a user error.

A product category can express reduced rates, exemptions, and category-specific tax rules that a yes-or-no `taxable` value can't. To use it, look up a category ID with the `taxonomy` query, pass the ID as `productCategoryId`, and read the saved category from the relevant `productCategory` field.

```
query {
  taxonomy {
    categories(search: "t-shirts", first: 5) {
      nodes {
        id
        fullName
      }
    }
  }
}
```

### Related docs

* [`DraftOrderLineItemInput`](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/DraftOrderLineItemInput)
* [`DraftOrderLineItem`](https://shopify.dev/docs/api/admin-graphql/latest/objects/DraftOrderLineItem)
* [`CalculatedDraftOrderLineItem`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CalculatedDraftOrderLineItem)
* [`orderEditAddCustomItem`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/orderEditAddCustomItem)
* [`CalculatedLineItem`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CalculatedLineItem)
* [`TaxonomyCategory`](https://shopify.dev/docs/api/admin-graphql/latest/objects/TaxonomyCategory)
* [`taxonomy`](https://shopify.dev/docs/api/admin-graphql/latest/queries/taxonomy)

## Clarification: Checkout footer visibility controls merchant-configurable content only

The visibility fields on `CheckoutBrandingFooterContent` and `CheckoutAndAccountsConfigurationBrandingFooterContent` now control only merchant-configurable footer content. All checkout and Thank you pages can display the additional Shopify-provided transaction information in the footer when visibility is set to `HIDDEN`.

Merchant-configurable footer content includes merchant policy links and copyright copy. Shopify-provided transaction information is part of checkout, isn't controlled by checkout branding, and isn't configurable through these visibility settings.

This affects apps that customize checkout branding for Shopify Plus stores through the legacy Checkout Branding API or the Checkout and Accounts Configuration API, especially apps that manage footer visibility, render branding previews, or run visual tests. Apps that don't manage checkout footer visibility are unaffected.

No fields, input types, enum values, access scopes, or mutations have changed. The clarification applies to every GraphQL Admin API version where the corresponding branding type exists; it isn't tied to a new API version.

Existing mutations and stored branding configurations continue to work without changes. If your app previews or tests checkout branding, update it so Shopify-provided transaction information can remain visible when merchant-configurable footer content is hidden.

### Related docs

* [`CheckoutBrandingFooterContent`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CheckoutBrandingFooterContent)
* [`CheckoutBrandingFooterContentInput`](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/CheckoutBrandingFooterContentInput)
* [`CheckoutAndAccountsConfigurationBrandingFooterContent`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CheckoutAndAccountsConfigurationBrandingFooterContent)
* [`CheckoutAndAccountsConfigurationBrandingFooterContentInput`](https://shopify.dev/docs/api/admin-graphql/latest/input-objects/CheckoutAndAccountsConfigurationBrandingFooterContentInput)
