Variants
Requires scope merchant-items-detail.
Lists one product’s variants with the merchant price, the storefront price pair, and the canonical product URL.
Authorization
merchantKey The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.
In: header
Path Parameters
Query Parameters
1 <= value <= 100Header Parameters
A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.
Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/products/20418/variants?limit=2" \ -H "X-Client-Key: {{merchantKey}}"{ "data": [ { "id": 7731, "uid": "019a1d52-5f10-7a02-8c61-0b2d4e6f8a31", "sku": "ADF-CHP-50CL", "title": "50cl", "option_values": { "Size": "50cl" }, "price": "2500.00", "storefront_price": "2500.00", "storefront_compare_at_price": null, "url": "https://adeyemifoods.com/products/homemade-chapman", "compare_at_price": null, "stock": 36, "track_inventory": true, "is_digital": false, "is_active": true, "is_backorder": false, "backorder_ready_date": null, "weight": 0.55, "position": 0, "created_at": "2026-07-15T11:30:00+01:00", "updated_at": "2026-09-22T16:05:00+01:00" }, { "id": 7732, "uid": "019a1d52-5f10-7a02-8c61-0b2d4e6f8a32", "sku": "ADF-CHP-1L", "title": "1 litre", "option_values": { "Size": "1 litre" }, "price": "4200.00", "storefront_price": "4200.00", "storefront_compare_at_price": null, "url": "https://adeyemifoods.com/products/homemade-chapman", "compare_at_price": null, "stock": 24, "track_inventory": true, "is_digital": false, "is_active": true, "is_backorder": false, "backorder_ready_date": null, "weight": 1.05, "position": 1, "created_at": "2026-07-15T11:30:00+01:00", "updated_at": "2026-09-22T16:05:00+01:00" } ], "has_more": true, "next_cursor": "eyJpZCI6NzczMiwiX3BvaW50c1RvTmV4dEl0ZW1zIjp0cnVlfQ"}Requires scope merchant-items-update.
Creates a variant on a product; answers the variant with the merchant price, the storefront price pair, and the canonical product URL.
Authorization
merchantKey The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.
In: header
Path Parameters
Header Parameters
A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.
Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.
Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
One variant of a shop product. title is not accepted: it is derived from the
option values ("Large / Red") by the variant service, as on every other writer.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/products/20418/variants" \ -H "X-Client-Key: {{merchantKey}}" \ -H "Content-Type: application/json" \ -d '{ "option_values": { "Size": "1 litre" }, "sku": "ADF-CHP-1L", "price": "4200.00", "stock": 24, "weight": 1.05, "position": 1 }'{ "status": "success", "message": "Variant created", "data": { "id": 7732, "uid": "019a1d52-5f10-7a02-8c61-0b2d4e6f8a32", "sku": "ADF-CHP-1L", "title": "1 litre", "option_values": { "Size": "1 litre" }, "price": "4200.00", "storefront_price": "4200.00", "storefront_compare_at_price": null, "url": "https://adeyemifoods.com/products/homemade-chapman", "compare_at_price": null, "stock": 24, "track_inventory": true, "is_digital": false, "is_active": true, "is_backorder": false, "backorder_ready_date": null, "weight": 1.05, "position": 1, "created_at": "2026-07-15T11:30:00+01:00", "updated_at": "2026-07-15T11:30:00+01:00" }}Requires scope merchant-items-update.
Updates a variant’s price, stock and attributes; answers the variant with the merchant price, the storefront price pair, and the canonical product URL.
Authorization
merchantKey The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.
In: header
Path Parameters
Header Parameters
A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.
Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.
Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Same fields as a new variant, every one optional: only what is sent changes.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PATCH "https://example.com/products/20418/variants/7732" \ -H "X-Client-Key: {{merchantKey}}" \ -H "Content-Type: application/json" \ -d '{ "price": "4200.00", "stock": 24 }'{ "status": "success", "message": "Variant updated", "data": { "id": 7732, "uid": "019a1d52-5f10-7a02-8c61-0b2d4e6f8a32", "sku": "ADF-CHP-1L", "title": "1 litre", "option_values": { "Size": "1 litre" }, "price": "4200.00", "storefront_price": "4200.00", "storefront_compare_at_price": null, "url": "https://adeyemifoods.com/products/homemade-chapman", "compare_at_price": null, "stock": 24, "track_inventory": true, "is_digital": false, "is_active": true, "is_backorder": false, "backorder_ready_date": null, "weight": 1.05, "position": 1, "created_at": "2026-07-15T11:30:00+01:00", "updated_at": "2026-09-22T16:05:00+01:00" }}Requires scope merchant-items-update.
Deletes a variant. A product’s last variant cannot be deleted.
Authorization
merchantKey The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.
In: header
Path Parameters
Header Parameters
A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.
Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.
Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X DELETE "https://example.com/products/20418/variants/7731" \ -H "X-Client-Key: {{merchantKey}}"{ "status": "success", "message": "Variant deleted", "data": { "id": 7731, "uid": "019a1d52-5f10-7a02-8c61-0b2d4e6f8a31", "deleted": true }}