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
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Product UUID |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
items | array | Yes | Replace-all gallery membership. May be []. Each entry is a Media Item (file_url + type, optional thumbnail_url). |
draft_version | integer | Draft only | Current 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"
}