# Storefront carts

A shopper's cart on the Storefront API: create it, add and change lines, set a note, attributes, buyer and discount codes, and read it back by its id.

A Storefront cart is the basket a shopper fills before checkout, and the simulator keeps it as Shopify does: `cartCreate` makes one, the `cart…` mutations change it and `cart(id:)` reads it. Create a cart with two units of a variant, add another variant and a note, and read the cart back:

```bash
STOREFRONT="$RYSTIC_URL/api/2026-10/graphql.json"
curl -s "$STOREFRONT" -H "X-Shopify-Storefront-Access-Token: placeholder" -H "Content-Type: application/json" -d '{"query": "mutation { cartCreate(input: {lines: [{merchandiseId: \"gid://shopify/ProductVariant/1040\", quantity: 2}]}) { cart { id totalQuantity checkoutUrl } userErrors { message } } }"}' | jq -c '.data.cartCreate.cart | {id, totalQuantity}'
# -> {"id":"gid://shopify/Cart/c000000000001?key=00000001","totalQuantity":2}
curl -s "$STOREFRONT" -H "X-Shopify-Storefront-Access-Token: placeholder" -H "Content-Type: application/json" -d '{"query": "mutation { cartLinesAdd(cartId: \"gid://shopify/Cart/c000000000001?key=00000001\", lines: [{merchandiseId: \"gid://shopify/ProductVariant/1041\", quantity: 1}]) { cart { totalQuantity } userErrors { message } } }"}' | jq -c '.data.cartLinesAdd.cart'
# -> {"totalQuantity":3}
curl -s "$STOREFRONT" -H "X-Shopify-Storefront-Access-Token: placeholder" -H "Content-Type: application/json" -d '{"query": "mutation { cartNoteUpdate(cartId: \"gid://shopify/Cart/c000000000001?key=00000001\", note: \"Gift wrap\") { cart { note } userErrors { message } } }"}' | jq -c '.data.cartNoteUpdate.cart'
# -> {"note":"Gift wrap"}
curl -s "$STOREFRONT" -H "X-Shopify-Storefront-Access-Token: placeholder" -H "Content-Type: application/json" -d '{"query": "{ cart(id: \"gid://shopify/Cart/c000000000001?key=00000001\") { id totalQuantity note } }"}' | jq -c '.data.cart'
# -> {"id":"gid://shopify/Cart/c000000000001?key=00000001","note":"Gift wrap","totalQuantity":3}
```

### Cart ids

A cart's id carries its key, `gid://shopify/Cart/<token>?key=<key>`, and every mutation and read takes the whole id. The first cart a simulator makes is `c000000000001` with key `00000001`, and the ids restart on reset. The default scenario's own cart is `gid://shopify/Cart/c1acme1190?key=a1190k`.

### What a cart holds

A cart's `totalQuantity` follows its lines: `cartLinesAdd`, `cartLinesUpdate` and `cartLinesRemove` move it. A cart also holds a note, attributes, a buyer identity, discount codes, delivery addresses, selected delivery options and metafields, each with its own mutation.

A discount code is recorded on the cart and reported `applicable: false`, because the simulator holds no discounts to apply it.

### Refusals

`cartCreate` and `cartLinesAdd` refuse a variant the store does not hold: they return `cart: null` and one user error. For variant 9, the error has code `INVALID` and the message `The merchandise with id gid://shopify/ProductVariant/9 does not exist.`, on this field:

| Mutation | User error `field` |
|---|---|
| `cartCreate` | `["input", "lines", "0", "merchandiseId"]` |
| `cartLinesAdd` | `["lines", "0", "merchandiseId"]` |

A mutation that names a cart the simulator does not hold returns one of four results:

| Mutation | Result for an unknown cart |
|---|---|
| `cartLinesAdd` | `cart: null` and the user error `The specified cart does not exist.` on `["cartId"]` |
| `cartNoteUpdate`, `cartLinesUpdate`, `cartSelectedDeliveryOptionsUpdate`, `cartDeliveryAddressesAdd` | a `null` payload and a top-level error with code `NOT_FOUND` |
| `cartAttributesUpdate`, `cartBuyerIdentityUpdate`, `cartDiscountCodesUpdate`, `cartLinesRemove`, the other three `cartDeliveryAddresses…` mutations | `cart: null` and an empty `userErrors` |
| `cartMetafieldsSet`, `cartMetafieldDelete` | the result for a cart that exists, since they do not check the cart |

### Checkout

A cart's `checkoutUrl` points back at the simulator, on the host you reached it on.

**Differs from Shopify:** no checkout page is served behind `checkoutUrl`.

Read `checkoutUrl` to test that your code hands the shopper on, and treat the order as a record you seed.

---

Source: https://www.rystic.ai/docs/simulators/shopify/features/storefront-carts · Markdown: https://www.rystic.ai/docs/simulators/shopify/features/storefront-carts.md
