Skip to main content

Update Product Media

Replace the product gallery in full. Array order is display order. items: [] clears the gallery. Integer media ids are never accepted or returned.

This does not change the cover (image_url). Host new bytes with Upload Product Media first, then send the returned file_url here. See Checkout appearance and Product images.

Live writes return 409 when the product has has_draft: true — see Live writes while a draft exists. Updating a published product requires an active Easytools plan — see Active plan required. Drafts can always be updated. Overlay writes require draft_version and return it plus preview_url.

Request

Live:

PATCH /products/{id}/media

Draft:

PATCH /products/{id}/draft/media

Path Parameters

ParameterTypeRequiredDescription
idstringYesProduct UUID

Request Body

ParameterTypeRequiredDescription
itemsarrayYesReplace-all gallery membership. May be []. Each entry is a Media Item (file_url + type, optional thumbnail_url).
draft_versionintegerDraft onlyCurrent overlay version from Get Product Draft. Minimum 1. A mismatch returns 409.

items[].type is image or video (file returns 422). file_url is the gallery locator — the same key the host upload returns. Omit thumbnail_url to keep the matching file_url's stored thumbnail; send JSON null to clear it.

Unknown keys return 422.

Example Request

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb/media" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"file_url": "https://cdn.example.com/products/7f3a1c2e-9b4d-4e8a-a1c6-2d5e8f0b3a19.webp",
"type": "image"
}
]
}'

Clear the gallery:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb/media" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": []
}'

Draft update adds "draft_version": 12 to the body and uses /draft/media.

Response

Success Response (200)

Live returns { "items": [ … ] } in the new order. Draft adds draft_version and preview_url. Each item is a Media Item Object.

{
"items": [
{
"file_url": "https://cdn.example.com/products/7f3a1c2e-9b4d-4e8a-a1c6-2d5e8f0b3a19.webp",
"type": "image",
"thumbnail_url": null
}
]
}

Error Responses

Bad Request (400)

{
"message": "Invalid product ID"
}

Product Not Found (404)

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

Conflict Error (409 — Unpublished Draft)

Live write while has_draft is true:

{
"message": "This product has an unpublished draft. Publish, unpublish, or delete the draft before making live changes."
}

Conflict Error (409 — Stale Draft Version)

Draft write when draft_version does not match:

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

Validation Error (422 Unprocessable Entity)

{
"message": "The given data was invalid.",
"errors": {
"items.0.type": [
"The selected items.0.type is invalid."
]
}
}

Missing items, a missing file_url, or type: "file" on a gallery item also return 422.

Publishing Not Allowed (422 — No Active Plan)

Live write against a published product when the store has no active Easytools plan. Overlay writes are not gated this way.

{
"message": "Product cannot be published without an active Easytools plan"
}