Set one item's quantity in a cart; zero removes it
Sets how many of one item a cart holds, and answers the whole updated cart. This is the ONE way a cart's contents change.
POST /v1/commerce/cart/{id}/item
| Address | https://api.hanzo.ai/v1/commerce/cart/{id}/item |
| Method | POST |
| Operation | setCartItem |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Sets how many of one item a cart holds, and answers the whole updated cart.
This is the ONE way a cart's contents change. The quantity is the RESULT, not a delta: sending 3 leaves 3 however many were there before, so a retry is safe and a double-submit cannot double an order. ZERO REMOVES the line — there is deliberately no separate delete, because removal is the same act at the boundary value and a second spelling would be a second set of edge cases.
Name the item with EITHER product OR variant, never both. Prefer variant for anything sold in sizes, colours or tiers: the price and the stock belong to the variant, so a product-level line on a varianted product prices the wrong thing. Either may be given as an id or as the human key — a product's URL slug, a variant's SKU — which is what lets a storefront add to cart straight from a product page URL without a lookup first.
The item's price and name are CACHED onto the line as it is added, so the cart keeps the price the shopper was shown even if the catalog moves underneath it.
An item that resolves to nothing in the catalog is refused 400 and the cart is left exactly as it was; nothing is partially applied.
A named handler, not a closure, so zipdoc can lift this prose into the registry.
Request
5 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | ID is the cart to amend, from the path. |
id | body | string | — | ID is the cart to amend, from the path. |
product | body | string | — | Product names the catalog product to set, by its id or its URL slug. |
quantity | body | integer | — | Quantity is how many of that item the cart should hold AFTER this call — it is the resulting count, not a delta, so sending 3 twice leaves 3 and not 6. |
variant | body | string | — | Variant names the specific sellable variant to set, by its id or its SKU. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | Cart | ok |
200 body — 23 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
createdAt | body | string | — | CreatedAt is when the cart was opened, RFC3339. |
currency | body | string | — | Currency is the ISO 4217 code every amount below is denominated in. |
discountCents | body | integer | — | DiscountCents is what coupons and promotions took off, in whole cents. |
email | body | string | — | Email is the shopper's address, when the cart carries one. |
id | body | string | — | ID is the cart's id — what every other cart op addresses it by, and what a storefront persists against the browser session. |
items | body | CartItem[] | — | Items are the cart's lines, in the order they were added. |
items[].free | body | boolean | — | Free reports a line that costs nothing because a coupon or a promotion made it so, rather than because its price is zero. |
items[].id | body | string | — | ID is the line's identity — the variant id when the line is a variant, otherwise the product id. |
items[].kind | body | string | — | Kind is "variant" when this line is a specific sellable variant and "product" when it is the product itself. |
items[].name | body | string | — | Name is the item's display name, cached onto the line when it was added so a cart renders without a second read. |
items[].priceCents | body | integer | — | PriceCents is the unit price in whole cents, cached at the moment the line was added. |
items[].quantity | body | integer | — | Quantity is how many units of this item the cart holds. |
items[].sku | body | string | — | SKU is the line's stock-keeping unit — the variant's when it has one, otherwise the product's. |
lineTotalCents | body | integer | — | LineTotalCents is the sum of the lines before any discount, in whole cents. |
order | body | string | — | Order is the order this cart became, once checkout completed it. |
shippingCents | body | integer | — | ShippingCents is the shipping charge, in whole cents. |
status | body | string | — | Status is "active" for a cart still being filled, "ordered" once checkout turned it into an order, and "discarded" when the shopper abandoned it. |
store | body | string | — | Store is the storefront the cart is being filled on. |
subtotalCents | body | integer | — | SubtotalCents is LineTotalCents less DiscountCents, in whole cents. |
taxCents | body | integer | — | TaxCents is the sales tax, in whole cents. |
totalCents | body | integer | — | TotalCents is what the shopper pays: subtotal plus shipping plus tax, in whole cents. |
updatedAt | body | string | — | UpdatedAt is when the cart was last amended, RFC3339. |
user | body | string | — | User is the signed-in shopper this cart belongs to, empty for a guest cart. |
Failure carries the platform error shape — see Errors.
Examples
hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.
import { Configuration, CommerceApi } from 'hanzoai';
const api = new CommerceApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.setCartItem({ id: 'id', id: "<id>", product: "<product>" });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import CommerceApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = CommerceApi(client).set_cart_item(id='id', id="<id>", product="<product>")cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.CommerceAPI.SetCartItem(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, commerce_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = commerce_api::set_cart_item(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.CommerceApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new CommerceApi(client).setCartItem();curl -X POST https://api.hanzo.ai/v1/commerce/cart/<id>/item \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "<id>",
"product": "<product>"
}'Tool commerce, op setCartItem — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "commerce",
"arguments": {
"op": "setCartItem",
"input": {
"id": "<id>",
"product": "<product>"
}
}
}
}'How is this guide?