Skip to content

Add to Cart

Add a product to the shopping cart. The request body depends on the product type — simple and virtual need only productId + quantity, while configurable, bundle, grouped, and downloadable products require their option selections.

Endpoint

POST /api/shop/add-product-in-cart

Authentication

This endpoint operates on a specific cart, so every request needs a cart token (Bearer), in addition to the storefront key:

HeaderRequiredDescription
X-STOREFRONT-KEYYesYour storefront API key
AuthorizationYesBearer <token> — a guest cart token or a logged-in customer token
Content-TypeYesapplication/json

Get a guest cart token first with Create Cart (POST /api/shop/cart-tokens) — its cartToken is the Bearer value. For a logged-in customer, use the token from Customer Login.

Request body by product type

All types take productId and quantity. Add the fields for the product's type:

FieldTypeApplies toDescription
productIdintegerallThe product ID being added
quantityintegerallQuantity (minimum 1)
selectedConfigurableOptionintegerconfigurableRequired. The chosen variant product ID.
superAttributeobjectconfigurable{ "<attributeId>": <optionId> }. Accepted but not used by add-to-cart — the cart resolves the variant from selectedConfigurableOption, so always send that.
bundleOptionsobjectbundle{ "<optionId>": [<bundleOptionProductId>, …] } — the bundle-option-product IDs (from the product detail), not raw product IDs.
bundleOptionQtyobjectbundle{ "<optionId>": <qty> } — quantity per bundle option
groupedQtyobjectgrouped{ "<associatedProductId>": <qty> } — include every associated product
linksarraydownloadable[<linkId>, …] — selected download-link IDs
customizableOptionsobjectsimple / virtual / downloadable{ "<optionId>": [<valueId>, …] } — chosen customizable-option values. See below.

The option IDs (variant product IDs, bundle-option-product IDs, associated product IDs, link IDs) come from the product detail response — fetch the product first to discover them. The product, variant, and bundle-option products must be active and in stock, or the item is rejected.

Customizable options

Customizable options are extra inputs an admin attaches to a product (a weight dropdown, a flavour picker, an engraving text field). They are not limited to configurable products — a simple or virtual product can carry them. Read them from the product's customizableOptions (Get Product): each option has an id and a prices array whose entries each have an id (the value id), and isRequired marks the mandatory ones.

Send the selections as customizableOptions — a map of option id → an array of chosen value ids:

json
"customizableOptions": { "9": [9], "10": [12] }

Option 9 (Weight) → value 9 (1kg); option 10 (Flavour) → value 12 (Pineapple). The array form supports multi-select; for a text/textarea option the array holds the entered string. Include every option whose isRequired is true, or the request returns 422. The chosen values come back on the cart item's options so you can show them on the cart page.

File-type customizable options

A file-type option needs a file upload, which cannot travel in a JSON body. Upload the file first at Upload Customizable File (a separate REST call that returns a token), then send the token here as that option's value:

json
"customizableOptions": { "9": [9], "10": [12], "11": ["<upload-token>"] }

The full flow, endpoint, and rules are on the Upload Customizable File page.

Use the example dropdown (top-right) to see the exact body for each product type.

Response

On success the endpoint returns the full updated cart (HTTP 200), not just the added line. Key fields:

FieldTypeDescription
idintegerCart ID
itemsCountintegerNumber of line items
itemsarrayCart line items (each with productId, name, quantity, type, options, formattedTotal, …)
subtotal / grandTotaldecimalCart totals (raw)
formattedSubtotal / formattedGrandTotalstringLocalised, currency-formatted totals
couponCodestring|nullApplied coupon, if any
successbooleanWhether the add succeeded
messagestringHuman-readable result

Behavior

  • If the same product (same options) is already in the cart, its quantity is increased.
  • Stock and saleability are validated; an inactive/out-of-stock item is rejected.
  • Booking products are added through the booking-specific flow, not this endpoint.

Released under the MIT License.