Search Documentation
Search for a documentation page...
Variants API
REST API endpoints for managing product variants (SKU, price, stock, options).
Product variants represent the purchasable versions of a product — different sizes, colors, or configurations. Each variant has its own SKU, price, stock level, and optional image.
Get Variant
Returns a variant by UUID or SKU code, including product info and price.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
currency | string | Currency code for price resolution (e.g. EUR) |
stock is null when the merchant does not track inventory for the variant — it sells freely and has no quantity ceiling. Treat null as available, not as sold out; only 0 means sold out.
Update Variant
Partially updates a variant by UUID or SKU. Only the provided fields are changed.
Request Body
| Field | Type | Description |
|---|---|---|
sku | string | New SKU code |
barcode | string | null | Barcode (EAN, UPC, GTIN, ISBN, or internal). Pass null to clear. |
description | string | null | Per-variant description (markdown, max 4000 chars), shown on the product page below the product summary. Pass null to clear. |
title | string | Variant display name (e.g. Large / Red) |
priceCents | number | Net price in cents (e.g. 2999 = $29.99) |
priceGrossCents | number | Gross price in cents — converted to net using the tax rate assigned to the variant's product. Send instead of priceCents, never both. |
prices | object | Per-currency prices as decimals (e.g. { "EUR": 25.99 }). Upserts by currency — an existing price for that currency is overwritten. The base/store currency is set via priceCents/priceGrossCents, not here. |
images | string[] | Replace the variant's images. External URLs are uploaded to the store's CDN; URLs already on the CDN pass through. [] removes all images. |
imageUrl | string | null | Deprecated — prefer images. Single variant image URL (null to remove). External URLs are now uploaded to the store's CDN (previously stored verbatim). Cannot be combined with images. |
stock | number | Inventory quantity. Setting it also puts the variant under inventory tracking — a variant created without stock sells freely until the first level is written here. |
options | object | Option label → value map (e.g. { "Zapach": "Black Fig" }). Replaces this variant's option set, rebuilding the variant types/values/combinations that drive the storefront picker. |
attributes | object[] | Per-variant key/value rows shown on the product page, e.g. [{ "key": "Nuty zapachowe", "value": "bergamotka, cedr" }]. Each entry is { key, value, checked? }; the array replaces whatever is stored. |
Sending both images and imageUrl returns 400. Sending both priceCents and priceGrossCents is rejected too — pick one. The rate used for the gross → net conversion is resolved from the variant's product; with no rate assigned, gross and net are identical. Both fields are cents (integer minor units), unlike the decimal price/priceGross on POST /api/v1/products — see Prices and tax.
A stock change goes through the same inventory pipeline the admin uses: the movement is recorded on the variant's stock history, back-in-stock notification emails go out when the variant moves from zero to a positive level, and the cached storefront reads that embed stock are invalidated immediately.
To write the shopper-facing gross amount instead, send priceGrossCents — at 23% VAT, 3689 gross stores 2999 net:
Delete Variant
Permanently deletes a variant by UUID or SKU. Cannot delete the last variant of a product.
A rolling subscription programme is sold as exactly one price, so its variants are locked: deleting a variant whose product has subscriptionMode: "rolling" is refused with 409 and the code rolling_variants_locked in the hint. Change the programme's price in the admin under Subscriptions → Rolling instead.
Returns 204 No Content on success.