Skip to main content

Update Product

Update an existing product in your store. This endpoint uses PATCH semantics, meaning only the fields you include in the request body will be updated.

Updating a product that is currently published requires an active Easytools plan, because the change goes live immediately. If the store has none, the call returns 422 and nothing is changed. Updating a draft is always accepted. See Active plan required.

Request

PATCH /products/{id}

Path Parameters

ParameterTypeRequiredDescription
idstringYesProduct UUID

Request Body

All fields are optional. Only include the fields you want to update.

ParameterTypeDescription
namestringProduct name (max 255 characters)
descriptionstringProduct description (max 10,000 characters). Set to null to clear.
slugstringCustom URL slug. Must match pattern ^[a-z0-9-]+$ and be unique per store.
image_urlstringURL to the product image (max 2048 characters). The image is downloaded and stored — see Product images. Set to null to remove.
fileobjectSingle downloadable file. Legacy shortcut equivalent to files: [file]. Set to null to remove. See File Object.
filesarrayUp to 5 downloadable files. Each entry is a File Object. When provided, this supersedes file and replaces the product's entire file set. Send [] to remove all files.
active_fromstringStart selling date (ISO 8601 format). Set to null to clear.
active_untilstringStop selling date (ISO 8601 format). Set to null to clear.
show_active_until_counterbooleanShow countdown timer on checkout page
redirect_urlstringPost-purchase redirect URL (max 1000 characters). Set to null to clear.
redirect_timeintegerRedirect delay in seconds
add_redirect_paramsbooleanInclude order parameters in redirect URL
webhook_urlstringWebhook URL for order events (max 255 characters). Set to null to use global webhook.
terms_urlstringTerms & conditions URL (max 255 characters). Set to null to clear.
policy_urlstringPrivacy policy URL (max 255 characters). Set to null to clear.
contact_emailstringProduct contact email. Set to null to clear.
refund_daysintegerRefund period in days. Set to 0 to disable refunds.
delegablebooleanAllow order delegation/gifting
show_discount_fieldbooleanShow promo code field on checkout page
hide_tax_id_fieldbooleanHide tax ID field on checkout page
require_tax_idbooleanRequire tax ID on checkout page
photo_zoomablebooleanEnable image zoom on checkout page
show_confettibooleanShow confetti animation after purchase
generate_qr_codebooleanGenerate QR code for product

Every URL in the body must start with http:// or https:// and include a host. See URL fields for what is accepted and what returns 422.

File Object

ParameterTypeRequiredDescription
namestringYesDisplay name shown in the customer portal (max 100 characters)
urlstringYesThe file's location (max 2048 characters): a URL to attach the file by link, or the url of a file read back from the API

Reads add a read-only third property, download_url — see File Object. Requests take name and url only, so a file kept from an earlier read is sent back without it.

note

A product can have up to 5 downloadable files. Updating files (or the legacy file) replaces the product's entire file set — include every file you want to keep. Send files: [] (or file: null) to remove all files.

Example Request

Update product name and description:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Product Name",
"description": "New and improved description"
}'

Update availability settings:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"active_from": "2026-02-01T00:00:00Z",
"active_until": "2026-03-01T00:00:00Z",
"show_active_until_counter": true
}'

Update checkout options:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"redirect_url": "https://mysite.com/thank-you",
"redirect_time": 5,
"add_redirect_params": true,
"show_discount_field": true,
"show_confetti": true
}'

Replace the product's downloadable files with multiple files:

curl -X PATCH "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"files": [
{ "name": "My ebook.pdf", "url": "https://mysite.com/ebook.pdf" },
{ "name": "Bonus chapter.pdf", "url": "https://mysite.com/bonus-chapter.pdf" }
]
}'

Response

Success Response (200)

Returns the updated product with all fields.

{
"id": "0632bef5-c308-42cd-9cba-89a7a4f722bb",
"status": "published",
"name": "Updated Product Name",
"description": "New and improved description",
"slug": "premium-coffee-beans",
"image_url": "https://example.com/images/coffee-beans.jpg",
"checkout_url": "https://cart.easy.tools/checkout/0632bef5-c308-42cd-9cba-89a7a4f722bb",
"currency": "usd",
"file": {
"name": "My ebook.pdf",
"url": "https://mysite.com/ebook.pdf",
"download_url": "https://cart.easy.tools/api/v1/product-files/9c1e7f42-3b8a-4d6e-9f10-2a5c7d3e8b41/download?expires=1749384000&signature=abc123"
},
"files": [
{
"name": "My ebook.pdf",
"url": "https://mysite.com/ebook.pdf",
"download_url": "https://cart.easy.tools/api/v1/product-files/9c1e7f42-3b8a-4d6e-9f10-2a5c7d3e8b41/download?expires=1749384000&signature=abc123"
},
{
"name": "Bonus chapter.pdf",
"url": "https://mysite.com/bonus-chapter.pdf",
"download_url": "https://cart.easy.tools/api/v1/product-files/4f7a2d18-6c93-4e5b-8a21-0d9e3f6b7c52/download?expires=1749384000&signature=abc123"
}
],
"active_from": "2026-02-01T00:00:00+00:00",
"active_until": "2026-03-01T00:00:00+00:00",
"show_active_until_counter": true,
"redirect_url": "https://mysite.com/thank-you",
"redirect_time": 5,
"add_redirect_params": true,
"webhook_url": null,
"terms_url": null,
"policy_url": null,
"contact_email": null,
"refund_days": 14,
"delegable": false,
"show_discount_field": true,
"hide_tax_id_field": false,
"require_tax_id": false,
"photo_zoomable": false,
"show_confetti": true,
"generate_qr_code": false,
"variants": [
{
"id": "d91c65aa-b221-4aa4-b626-cf0d8a198749",
"type": "one_time",
"recurring_options": null,
"name": "250g Package",
"amount": 1999
}
]
}

Response Fields

See Get Product for a complete list of response fields.

Error Responses

Bad Request (400)

{
"message": "Invalid product ID"
}

Product Not Found (404)

{
"message": "Product with ID b2c8e4a1-9d3f-4e7b-a5c2-1f6d8b3e9a47 not found"
}

Validation Error (422 Unprocessable Entity)

{
"message": "The given data was invalid.",
"errors": {
"slug": [
"The slug 'existing-slug' is already in use by another product."
]
}
}
{
"message": "The given data was invalid.",
"errors": {
"slug": [
"The slug field format is invalid."
],
"active_until": [
"The active until field must be a date after or equal to active from."
]
}
}

Publishing Not Allowed (422 — No Active Plan)

Returned when the product is currently published and the store has no active Easytools plan. Nothing is changed. Activate a plan and retry — repeating the call as it stands returns the same error. Drafts are unaffected.

This body carries a message and no errors key, so a 422 from this endpoint is distinguished by whether errors is present.

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

Notes

  • Currency: The currency field cannot be changed after a product is created. Create a new product to use a different currency.