Skip to main content

Update Product Draft Variant

Sparse-update a variant on a product's unpublished overlay. Buyers still see the live product.

draft_version is required. The same field allowlist as Update Product Variant applies. amount, type, currency, tax_behavior, and recurring_options cannot be changed after create. Sending any of them returns 422 and nothing is changed — see Immutable price fields.

Unpublished overlay variants are nested-only — they are not reachable at Update Product Variant. Sending custom_fields is ignored — use the nested Custom Fields overlay paths.

Request

PATCH /products/{productId}/draft/variants/{id}

Path Parameters

ParameterTypeRequiredDescription
productIdstringYesProduct UUID
idstringYesProduct variant UUID

Request Body

ParameterTypeRequiredDescription
draft_versionintegerYesCurrent overlay version from Get Product Draft or a prior draft write. Minimum 1. A mismatch returns 409.

All other fields are optional and match Update Product Variant. Only include the fields you want to change.

Example Request

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb/draft/variants/5272bfcf-4e92-458d-b513-80ca474a16e4" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"draft_version": 9,
"name": "100g Sample - roasted"
}'

Attach same-product upsells on the overlay. The target must already be a published sibling — a variant created only on this overlay and not yet published returns 422. See Upsells:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb/draft/variants/d91c65aa-b221-4aa4-b626-cf0d8a198749" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"draft_version": 9,
"upsells": [
{
"variant_id": "e903c6d6-163e-4080-a99a-4ee5a1e4f17a",
"text": "Switch to a monthly subscription"
}
]
}'

Response

Success Response (200)

Returns the updated overlay variant plus the new draft_version and a fresh product preview_url. See Draft preview.

{
"id": "5272bfcf-4e92-458d-b513-80ca474a16e4",
"status": "published",
"type": "one_time",
"recurring_options": null,
"name": "100g Sample - roasted",
"amount": 999,
"currency": "usd",
"checkout_url": null,
"draft_version": 10,
"preview_url": "https://cart.easy.tools/checkout-preview/0632bef5-c308-42cd-9cba-89a7a4f722bb?expires=1749384000&signature=abc123"
}

The response contains the full variant plus draft_version and preview_url. See Get Product Variant for the complete list of variant fields; the example above is abbreviated.

Response Fields

Shared variant fields are listed on Get Product Variant. This write adds:

FieldTypeNullableDescription
draft_versionintegerNoNew overlay version after this write. Send it on the next draft write.
preview_urlstringNoTemporary signed checkout preview of the product. Always reminted. Expires after about one hour. See Draft preview.

Error Responses

Bad Request (400)

Returned when the product UUID or the variant UUID is malformed.

{
"message": "Invalid product ID"
}
{
"message": "Invalid variant ID"
}

Not Found (404)

Two cases share this status, told apart by the message. The product UUID does not exist, belongs to another store, or points at an archived product:

{
"message": "Product with ID 0632bef5-c308-42cd-9cba-89a7a4f722bb not found"
}

Or the product resolves but the variant is not on its overlay:

{
"message": "Product variant with ID 5272bfcf-4e92-458d-b513-80ca474a16e4 not found"
}

Conflict Error (409 — Stale Draft Version)

Returned when draft_version does not match the current overlay version. GET the draft and retry with the current draft_version.

{
"message": "The draft was edited elsewhere. GET the draft and retry with the current draft_version."
}

Validation Error (422 Unprocessable Entity)

Returned when draft_version is missing, an immutable price field is sent, or the body fails the same field rules as Update Product Variant.

{
"message": "The given data was invalid.",
"errors": {
"draft_version": [
"The draft version field is required."
]
}
}
{
"message": "The amount field cannot be updated. Stripe does not allow changing the amount on a published price.",
"errors": {
"amount": [
"The amount field cannot be updated. Stripe does not allow changing the amount on a published price."
]
}
}