diff --git a/.changeset/pos-cart-update-line-item-quantity.md b/.changeset/pos-cart-update-line-item-quantity.md
new file mode 100644
index 0000000000..57f7d20903
--- /dev/null
+++ b/.changeset/pos-cart-update-line-item-quantity.md
@@ -0,0 +1,6 @@
+---
+'@shopify/ui-extensions': minor
+'@shopify/ui-extensions-tester': patch
+---
+
+Add `cart.updateLineItemQuantity` to the POS Cart API for API version 2026-10. The method updates one line item's quantity while preserving its properties, discounts, and selling plans.
diff --git a/packages/ui-extensions-tester/src/point-of-sale/README.md b/packages/ui-extensions-tester/src/point-of-sale/README.md
index a30a20cc41..81dc8ef8c6 100644
--- a/packages/ui-extensions-tester/src/point-of-sale/README.md
+++ b/packages/ui-extensions-tester/src/point-of-sale/README.md
@@ -49,9 +49,27 @@ extension.shopify.storage = createStorage({
});
```
-## 🔒 Mocking mutation return values
+## 🔒 Mocking cart mutations
-Replace mutation functions with `vi.fn()` and use `createResult()` to build typed return values. The first argument is the mutation name; the second is an optional result override.
+The target API mock includes asynchronous stubs for Cart API mutations, including `updateLineItemQuantity`. Replace a stub with a spy when you need to verify a call:
+
+```ts
+const updateLineItemQuantity = vi.spyOn(
+ extension.shopify.cart,
+ 'updateLineItemQuantity',
+);
+
+await extension.shopify.cart.updateLineItemQuantity(
+ 'line-item-uuid',
+ 2,
+);
+
+expect(
+ updateLineItemQuantity,
+).toHaveBeenCalledWith('line-item-uuid', 2);
+```
+
+For mutations that return data, replace the function with `vi.fn()` and use `createResult()` to build typed return values. The first argument is the mutation name; the second is an optional result override.
```ts
import {
diff --git a/packages/ui-extensions-tester/src/point-of-sale/factories.ts b/packages/ui-extensions-tester/src/point-of-sale/factories.ts
index 65a7596eeb..b581e0663e 100644
--- a/packages/ui-extensions-tester/src/point-of-sale/factories.ts
+++ b/packages/ui-extensions-tester/src/point-of-sale/factories.ts
@@ -224,6 +224,7 @@ function createMockCartApi(): CartApi {
removeCustomer: async () => {},
addCustomSale: async () => '',
addLineItem: async () => '',
+ updateLineItemQuantity: async () => {},
removeLineItem: async () => {},
addCartProperties: async () => {},
removeCartProperties: async () => {},
diff --git a/packages/ui-extensions-tester/src/tests/pos-resolution-targets.test.ts b/packages/ui-extensions-tester/src/tests/pos-resolution-targets.test.ts
index b3de09332e..599c42a9b0 100644
--- a/packages/ui-extensions-tester/src/tests/pos-resolution-targets.test.ts
+++ b/packages/ui-extensions-tester/src/tests/pos-resolution-targets.test.ts
@@ -17,6 +17,7 @@ describe('pos.cart.validations.resolution.render', () => {
expect(api.cart.current).toBeDefined();
expect(typeof api.cart.addLineItem).toBe('function');
+ expect(typeof api.cart.updateLineItemQuantity).toBe('function');
expect(api.scanner).toBeDefined();
});
diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/cart-api/update-line-item-quantity.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/cart-api/update-line-item-quantity.jsx
new file mode 100644
index 0000000000..072528f62b
--- /dev/null
+++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/cart-api/update-line-item-quantity.jsx
@@ -0,0 +1,23 @@
+import {render} from 'preact';
+
+export default async () => {
+ render(, document.body);
+};
+
+const Extension = () => {
+ return (
+ {
+ const [lineItem] = shopify.cart.current.value.lineItems;
+ if (lineItem) {
+ shopify.cart.updateLineItemQuantity(
+ lineItem.uuid,
+ lineItem.quantity + 1,
+ );
+ }
+ }}
+ />
+ );
+};
diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/api/cart-api/cart-api.ts b/packages/ui-extensions/src/surfaces/point-of-sale/api/cart-api/cart-api.ts
index d1aba4d46d..fbaf469a6b 100644
--- a/packages/ui-extensions/src/surfaces/point-of-sale/api/cart-api/cart-api.ts
+++ b/packages/ui-extensions/src/surfaces/point-of-sale/api/cart-api/cart-api.ts
@@ -138,6 +138,20 @@ export interface MutableCartApiContent {
options?: AddLineItemOptions,
): Promise;
+ /**
+ * Set the quantity of an existing line item identified by its `UUID`, preserving the line item's properties, discounts, and selling plans. This is equivalent to a merchant adjusting the quantity on the native cart line.
+ *
+ * If POS has split the line into multiple allocations that share the same `UUID` (for example, lines split across delivery methods), the target line is ambiguous and the call throws instead of guessing.
+ *
+ * Only available on API version `2026-10` and later.
+ *
+ * @param uuid the UUID of the line item to update
+ * @param quantity the new absolute quantity; must be an integer of 1 or greater. To remove a line item, use `removeLineItem` instead.
+ * @returns A promise that resolves after the cart state reflects the change.
+ * @throws {Error} if the line item is not found, the `UUID` matches multiple split-line allocations, the quantity is invalid, the cart is not editable because it is a return or exchange, or the POS app version does not support this method.
+ */
+ updateLineItemQuantity(uuid: string, quantity: number): Promise;
+
/**
* Remove a specific line item from the cart using its `UUID`. The line item will be completely removed from the cart along with any associated discounts, properties, or selling plans.
*