2026-04: Release notes
The 2026-04 release focuses on checkout settings, inventory safety, metafield and webhook migrations, payments, POS, and Storefront API changes.
Several changes in this version require code updates, especially around payment customizations, inventory mutation safety, webhooks, and metafields. Review and adjust affected integrations before adopting 2026-04.
2026-04 is stable and available for production use until at least April 1, 2027 at 15:00 UTC:
Anchor to GraphQL Admin APIGraph QL Admin API
GraphQL Admin API updates include checkout branding, inventory and fulfillment, metafields and metaobjects, payments, subscriptions, analytics, discounts, and app data.
Anchor to AppsApps
Apps updates add delegate token expiration data and tax calculation business entity details.
The delegateAccessTokenCreate mutation now returns expiresIn on DelegateAccessToken, showing the seconds remaining before a delegate token expires, including when the token inherits the parent token’s TTL.
Tax calculation requests sent to Tax Partner apps can now include a root-level merchant_business_entity object with id, company_name, display_name, and address details when the merchant has configured a business entity for the shop.
Anchor to Checkout and accounts configurationsCheckout and accounts configurations
The Checkout and Accounts Configuration API consolidates branding and settings for checkout, customer accounts, and sign-in.
The Checkout and Accounts Configuration API consolidates branding and settings for checkout, customer accounts, and sign-in for Shopify Plus merchants, replacing the deprecated Checkout Profile and Checkout Branding APIs with shared designTokens, components, surface overrides, direct colors, and market-specific branding.
Anchor to DiscountsDiscounts
Discounts now support tags.
Discounts now support a tags field across all discount types, so apps can label, group, and organize discounts. Tags can be added, updated, and removed through the GraphQL Admin API.
Anchor to InventoryInventory
Inventory updates add includeInactive to include inactive inventory levels in inventoryLevels and inventoryLevel queries, add isActive to identify whether returned inventory levels are active, preserve existing quantities when inventoryActivate omits quantity inputs, and add barcode fields and mutations for inventory shipments.
InventoryItem.inventoryLevels, InventoryItem.inventoryLevel, Location.inventoryLevels, and Location.inventoryLevel now accept an optional includeInactive boolean argument. Existing queries continue to return only active inventory levels unless includeInactive: true is passed.
InventoryLevel now includes an isActive boolean field to distinguish active and inactive inventory levels. Existing queries continue to return only active levels, but apps that include inactive levels can use isActive for filtering, display, and aggregations.
inventoryActivate no longer defaults available or onHand quantities to zero when those arguments are omitted. Previously active items at a location retain existing quantities on the inactive InventoryLevel, and inventory_levels/connect.json behaves the same way.
Inventory shipments now support unique barcodes through the nullable InventoryShipment.barcode field and optional InventoryShipmentCreateInput.barcode. Use inventoryShipmentSetBarcode to set or clear a shipment barcode, with validation for uniqueness, 255 character length, and whitespace handling.
Anchor to Inventory mutation safetyInventory mutation safety
Inventory mutations now require compare-and-swap quantities and idempotency for safer writes.
Update inventorySetQuantities calls to include changeFromQuantity, passing the expected current quantity for concurrency checks or changeFromQuantity: null to opt out. Remove compareQuantity and ignoreCompareQuantity from mutation inputs.
Update inventory mutation calls to include changeFromQuantity for inventoryAdjustQuantities, inventoryMoveQuantities, inventorySetOnHandQuantities, and productVariantsBulkUpdate. Pass the expected current quantity for concurrency checks, or explicitly pass changeFromQuantity: null to opt out.
Idempotency is mandatory for specific Shopify mutations starting in April 2026. Add idempotency to prevent duplicate inventory adjustments and refunds.
Dec 12, 2025Anchor to LocalizationsLocalizations
Metafields now support localized value queries.
The Metafield type now includes a translations field to query localized metafield values through the GraphQL Admin API. Register translations with translationsRegister using the metafield resource ID and compareDigest for supported text-based metafield types.
Anchor to MetafieldsMetafields
Metafield updates add cart-to-order copying and lower JSON write limits for new or non-grandfathered apps.
JSON metafield writes are limited to 128 KB, while other metafield type limits are unchanged and existing apps that used JSON fields before April 1, 2026 keep the 2 MB limit. Review new writes and request access if your new app requires larger JSON values.
Tax calculation request payloads for tax partner apps now include buyer metafields in cart.buyer_identity.customer.metafields[] for D2C orders and cart.buyer_identity.purchasing_company.company.metafields[] for B2B orders, with each metafield including namespace, key, type, and value.
Order metafield definitions now support the cartToOrderCopyable capability, which copies matching cart metafield values to order metafields when an order is created. Use cart metafields for custom buyer journey data instead of cart attributes or checkout metafields.
Anchor to MetaobjectsMetaobjects
Metaobjects updates simplify app-owned metaobject access by removing scope requirements, add createdAt and updatedAt fields to MetaobjectDefinition, and make fieldDefinitions optional when creating metaobject definitions.
Apps can read and write their own app-owned metaobjects, including declarative definitions with types like $app:example, without requesting access scopes. Merchant-owned metaobject types still require scopes such as read_metaobjects or write_metaobject_definitions.
MetaobjectDefinition now includes createdAt and updatedAt fields, so apps can query when a metaobject definition was created and last updated.
fieldDefinitions is now optional for the metaobjectDefinitionCreate mutation. Existing implementations that provide fieldDefinitions continue to work, and apps can omit it when creating a metaobject definition without fields.
Anchor to OrdersOrders
Order and subscription updates add subscription contract creation, granular payment errors, billing options, state modeling, and ShopifyQL field migrations.
paymentMethodId is now optional when creating subscription contracts with subscriptionContractAtomicCreate and subscriptionContractCreate, so apps can migrate contracts that have missing or expired payment methods.
OrderTransactionErrorCode now includes more granular payment decline values, and RISKY is deprecated in favor of FRAUD_SUSPECTED. Update error handling for OrderTransaction.errorCode to support the new codes and provide more specific customer messaging.
Update ShopifyQL analytics queries to replace deprecated Returns fields with renamed sales reversal fields, such as returns to sales_reversals and quantity_returned to reversed_quantity; definitions are unchanged. Deprecated fields are removed in version 2026-07 and remain accessible through older API versions until 2027-04.
subscriptionBillingAttemptCreate now accepts paymentProcessingPolicy to control billing attempts when a subscription contract lacks a valid payment method. Use SKIP_PAYMENT_AND_CREATE_UNPAID_ORDER to create an unpaid order, or omit it or use FAIL_UNLESS_VALID_PAYMENT_METHOD to require a valid payment method.
Adds SubscriptionBillingAttemptState, a discriminated union that replaces loosely typed nullable billing attempt fields such as errorCode, errorMessage, nextActionUrl, order, processingError, and ready with state-specific equivalents.
Subscription billing attempts in the GraphQL Admin API now return more granular SubscriptionBillingAttemptErrorCode values. This reduces generic AUTHENTICATION_ERROR and PAYMENT_METHOD_DECLINED results and makes payment failures easier to diagnose.
Anchor to Products and collectionsProducts and collections
Products and collections updates add product discount stacking, identifier lookup, gift card expiration settings, multi-channel management, tax calculation properties, analytics-queryable metafields, and inventory tracking filters.
The GraphQL Admin API adds expirationConfiguration on GiftCardConfiguration to query a merchant’s default gift card expiration settings. The field returns GiftCardExpirationConfiguration with expirationValue and expirationUnit, or null when gift cards never expire.
The GraphQL Admin API now supports applying multiple product discounts to a single cart line, so merchants can migrate Scripts before the June 30, 2026 sunset date. Use DiscountAutomaticBasic.combinesWith to configure discount combinations.
productUpdate now accepts an identifier argument to look up products by id, handle, or customId instead of passing the product ID in input. Use customId with a unique metafield namespace, key, and value.
Sales channel apps can create and manage multiple channel connections on a shop, and each connection can have a separate specification or external account. Add a Channel Config extension and use APIs such as channelCreate, channelUpdate, channelDelete, and channelFullSync to manage connections.
Tax calculation requests for Tax Partner apps can include selected cart line item properties in delivery_groups[].cart_lines[].properties. Apps can request up to five property keys, and only those keys are included for each line item when present.
MetafieldDefinition now supports the analyticsQueryable capability through MetafieldDefinition.capabilities, configurable with metafieldDefinitionCreate and metafieldDefinitionUpdate.
products query now supports a tracks_inventory Boolean filter, so apps can find products based on whether inventory tracking is enabled.
Anchor to Shipping and fulfillmentShipping and fulfillment
Shipping and fulfillment updates remove SKU sharing controls, add fulfillment order progress and error details, and deprecate legacy shipping profile fields.
Mutation deliveryShippingOriginAssign is deprecated because legacy mode shipping profiles are no longer supported. Action required: stop using deliveryShippingOriginAssign and use current API methods for assigning shipping origins.
permitsSkuSharing has been removed from FulfillmentService, fulfillmentServiceCreate, and fulfillmentServiceUpdate; SKU sharing is enabled for all fulfillment services. Remove reads and writes of permitsSkuSharing, and review logic that assumes inventory is stocked at only one location.
Remove dependencies on shipping legacy mode profile fields. DeliveryProfile.legacyMode is deprecated, while DeliverySetting.legacyModeBlocked, DeliverySetting.legacyModeProfiles, and DeliverySettingInput.legacyModeProfiles return static data or are ignored by mutations.
The fulfillmentOrderCancel mutation now returns a specific fulfillmentOrderCancelError type instead of generic userError, including a code field to support programmatic handling of restrictions when cancelling fulfillment orders with reported progress.
fulfillmentOrderMove now returns fulfillmentOrderMoveUserError instead of the generic userError, including a code field for programmatic handling. Moving fulfillment orders with reported progress is restricted, supporting manual in-progress fulfillment order reporting.
3PLs and fulfillment apps can report fulfillment order progress using fulfillmentOrderReportProgress, with optional reasonNotes. fulfillmentOrder.supportedActions returns REPORT_PROGRESS when available, and new webhooks track reported progress or when merchant-managed progress is stopped.
The FulfillmentOrder GraphQL type now includes remainingLineItemsWeight, which returns the total weight of line items that have not yet been fulfilled so apps can make fulfillment decisions based on remaining order weight.
Anchor to Store propertiesStore properties
ShopifyQL table data columns add rating, identity, and color types.
ColumnDataType in ShopifyqlTableDataColumn now includes RATING for float rating values, STRING_IDENTITY for GID or UUID values, and COLOR for HEX color values.
Anchor to WebhooksWebhooks
Webhook subscriptions add optional names for identification and routing.
The tax_summaries/create webhook for Tax Partner apps now includes a root-level merchant_business_entity field on the tax summary when the merchant has configured a business entity for the shop.
Webhook subscriptions can now include an optional name for easier identification and routing. Set name in shopify.app.toml or through WebhookSubscription, webhookSubscriptionCreate, and webhookSubscriptionUpdate; names are included in delivery request headers.
Anchor to Customer Account APICustomer Account API
Customer Account API adds draft order line item components.
Anchor to OrdersOrders
Draft order line items add component hierarchy controls.
DraftOrderLineItem now includes a components field that returns component line items for a parent line item. DraftOrder.lineItems also supports flattenComponents, which defaults to false and returns only top-level nodes unless set to true.
Anchor to Events & webhooksEvents & webhooks
Webhooks remove checkout identifiers from checkout and order payloads.
Anchor to OrderOrder
The id field was removed from checkouts/create and checkouts/update, and checkout_id was removed from affected orders/* webhooks. Update webhook handlers to use token for checkout webhooks and checkout_token for orders webhooks.
Anchor to FunctionsFunctions
Functions updates add script migration guidance, discount details, validation targets, metaobject access, and discount prerequisites.
Anchor to MigrationMigration
Shopify Scripts customizations must move to Shopify Functions.
Shopify Functions add capabilities for discounts, shipping, and payments to replace Shopify Scripts customizations. Migrate scripts using the customizations report. Editing and publishing stops April 15, 2026, and scripts stop executing June 30, 2026.
Apr 9, 2026Anchor to Cart and Checkout ValidationCart and Checkout Validation
Cart and Checkout Validation adds billing address and PO number error targets.
Cart and Checkout Validation Functions can now validate billingAddress and poNumber, with field-level error targets for $.cart.billingAddress.{field} and $.cart.poNumber. Existing functions continue to run unchanged, and these validations are optional.
Anchor to Cart TransformCart Transform
Cart Transform functions can access app-owned metaobjects.
Shopify Functions can now access app-owned metaobject entries from every function target. Query structured data such as tiered pricing or bundles by specifying a handle or ID in the input query; only $app metaobject types are accessible.
Anchor to DiscountDiscount
Discount functions add detailed discount input and prerequisites for Buy X, Get Y discounts.
Shopify Functions can access detailed discount information from cart, line item, and delivery group levels, including cart discount applications and discounts allocated to line items or delivery groups. Only functions that execute after discounts can see complete discount information.
Discount Functions product discount candidates now support a prerequisites field for Buy X, Get Y discounts. Define each prerequisite as a cartLinePrerequisite with the cart line id and required quantity for the Buy X condition.
Anchor to Payments Apps APIPayments Apps API
Payments Apps API adds granular rejection details.
The Payments Apps API adds more granular rejection codes to PaymentSessionStateRejectedReason for declined payment sessions, plus a new source field on PaymentSessionRejectionReasonInput and PaymentSessionStateRejected.
verificationSessionReject now supports RESOURCE_NOT_FOUND and RESOURCE_INVALID rejection reason codes on VerificationSessionStateReason. VerificationSessionRejectionReasonInput also adds optional merchantMessage for localized, merchant-facing rejection details.
Anchor to PolarisPolaris
Polaris updates include POS cash management, UI extension metafield changes, reference documentation versioning, testing tools, and discount UI fields.
Polaris reference docs now follow Shopify API versioning, and Shopify has added an official UI extension testing library.
Polaris reference docs now follow Shopify GraphQL API versioning: each stable version is supported for at least 12 months. Shopify.dev publishes docs for only the last four stable versions of Admin, Checkout, Customer Account, and POS UI extensions.
Apr 1, 2026Shopify now provides @shopify/ui-extensions-tester, an official testing library for UI extensions across Checkout, Admin, Customer Accounts, and POS. It includes typed shopify mocks, surface-specific defaults, DOM rendering, querying, and event simulation without a Shopify host.
Anchor to AdminAdmin
Discount UI extensions add purchase type and recurring billing cycle settings.
Discount UI extensions can now configure purchaseType and recurringCycleLimit through the discounts plugin for DiscountCodeApp and DiscountAutomaticApp discounts, letting merchants control purchase type eligibility and subscription billing cycle limits enforced at checkout.
Anchor to CheckoutCheckout
Checkout and customer account UI extensions must migrate from checkout metafields to cart and order metafields.
Apps using checkout metafields in older API versions must upgrade to API version 2026-04 and migrate to cart metafields in checkout UI extensions or order metafields in customer account UI extensions. Order metafield definitions can now copy values from cart metafields on order creation.
Shopify POS adds custom cash management resources and extension targets.
Shopify POS cash management now exposes GraphQL Admin API resources for custom workflows, including CashDrawer, cashDrawers, cashDrawerCreate, and pointOfSaleDeviceAssignToCashDrawer.
Anchor to Storefront APIStorefront API
Storefront API improves cart transform error reporting.
Anchor to CartCart
The Storefront API returns MERCHANDISE_LINE_TRANSFORMERS_RUN_ERROR when a Cart Transform Function encounters a runtime error during cart operations such as cartCreate or cartLinesAdd, replacing the previous generic INVALID error for this case.