Cart AJAX API
The cart API answers on the store’s own domain, so theme JavaScript calls it with relative URLs. Responses are JSON with prices in minor units, the same shape as Shopify’s.
| Request | Does |
|---|---|
GET /cart.js |
The cart. |
POST /cart/add.js |
Adds one or more variants. |
POST /cart/change.js |
Changes one line’s quantity or properties. |
POST /cart/update.js |
Changes several quantities, the note or attributes. |
POST /cart/clear.js |
Empties the cart. |
Requests take JSON (Content-Type: application/json) or form data. Without .js, POST /cart/add is a plain form post that redirects to the cart page: that’s what {% form 'product' %} does when JavaScript is off.
Add to cart
Section titled “Add to cart”const res = await fetch("/cart/add.js", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: variantId, quantity: 1, properties: { "Gift message": "Eid Mubarak" } }),});const item = await res.json(); // the added lineAdd several at once with { items: [{ id, quantity }, …] }; the answer is then { items: [...] }.
Change a line
Section titled “Change a line”await fetch("/cart/change.js", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: lineKey, quantity: 2 }), // or { line: 1, quantity: 0 } to remove the first line});id is the line’s key (or a variant ID when that variant is in the cart once); line is the 1-based position. Quantity 0 removes the line.
Update many
Section titled “Update many”await fetch("/cart/update.js", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ updates: { [lineKey]: 3 }, note: "Please call before delivery", attributes: { "Delivery slot": "Evening" } }),});updates is an object of line keys (or variant IDs) to quantities, or an array of quantities in line order.
The cart object
Section titled “The cart object”{ "token": "…", "item_count": 3, "total_price": 122000, "items_subtotal_price": 122000, "original_total_price": 122000, "total_discount": 0, "currency": "QAR", "note": "", "attributes": {}, "requires_shipping": true, "items": [ { "key": "…", "id": "…", "variant_id": "…", "product_id": "…", "title": "Embroidered linen abaya - M / Sand", "product_title": "Embroidered linen abaya", "variant_title": "M / Sand", "quantity": 2, "price": 45000, "final_price": 45000, "line_price": 90000, "final_line_price": 90000, "url": "/products/embroidered-linen-abaya?variant=…", "image": "https://…", "properties": {} } ], "cart_level_discount_applications": [], "discount_codes": []}Format prices on the page with the store’s currency: window.Sooquna.currency holds its code.
Errors
Section titled “Errors”Problems answer with an HTTP status and:
{ "status": 422, "message": "Cart Error", "description": "Only 2 left in stock." }Show description to the shopper.
Updating the page
Section titled “Updating the page”After a change, re-render the cart drawer and the header’s cart count with the section rendering API:
const html = await (await fetch(`${location.pathname}?sections=cart-drawer,sections--header-group__header`)).json();The product_added_to_cart event is sent for you after a successful add.js.
Was this page helpful?

