Skip to main content

Create Product

Create a new product in your store.

Creating a product with status: published requires an active Easytools plan. If the store has none, the call returns 422 and no product is created. status: draft is always accepted. See Active plan required.

Request

POST /products

Request Body

ParameterTypeRequiredDescription
statusstringYesProduct status ("draft" or "published")
namestringYesProduct name (max 255 characters)
descriptionstringNoProduct description (max 10,000 characters)
image_urlstringNoURL to the product image (max 2048 characters). The image is downloaded and stored — see Product images.
currencystringYesISO currency code (3 characters, e.g., "usd", "eur")
slugstringNoCustom URL slug. Must match pattern ^[a-z0-9-]+$ and be unique per store.
active_fromstringNoStart selling date (ISO 8601 format)
active_untilstringNoStop selling date (ISO 8601 format). Must be after or equal to active_from.
redirect_urlstringNoPost-purchase redirect URL (max 1000 characters)
webhook_urlstringNoWebhook URL for order events (max 255 characters)
terms_urlstringNoTerms & conditions URL (max 255 characters)
policy_urlstringNoPrivacy policy URL (max 255 characters)
contact_emailstringNoProduct contact email (max 255 characters)
refund_daysintegerNoRefund period in days. Set to 0 to disable refunds.
show_discount_fieldbooleanNoShow promo code field on checkout page
delegablebooleanNoAllow order delegation/gifting
fileobjectNoSingle downloadable file. Legacy shortcut equivalent to files: [file]. See File Object.
filesarrayNoUp to 5 downloadable files. Each entry is a File Object. When provided, this supersedes file.

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.

note

A product can have up to 5 downloadable files. Use files (array) to attach more than one. The singular file field is a backward-compatible shortcut for a single file; if both are sent, files wins.

Example Request

Basic product creation:

curl -X POST "https://cart.easy.tools/api/v1/products" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "published",
"name": "Premium Coffee Beans",
"description": "High-quality arabica coffee beans from Colombia",
"image_url": "https://example.com/images/coffee-beans.jpg",
"currency": "usd",
"file": {
"name": "My ebook.pdf",
"url": "https://mysite.com/ebook.pdf"
}
}'

Product with multiple downloadable files:

curl -X POST "https://cart.easy.tools/api/v1/products" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "published",
"name": "Premium Coffee Bundle",
"currency": "usd",
"files": [
{ "name": "My ebook.pdf", "url": "https://mysite.com/ebook.pdf" },
{ "name": "Bonus chapter.pdf", "url": "https://mysite.com/bonus-chapter.pdf" }
]
}'

Product with advanced options:

curl -X POST "https://cart.easy.tools/api/v1/products" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "published",
"name": "Premium Coffee Beans",
"description": "High-quality arabica coffee beans from Colombia",
"image_url": "https://example.com/images/coffee-beans.jpg",
"currency": "usd",
"slug": "premium-arabica-coffee",
"active_from": "2026-02-01T00:00:00Z",
"active_until": "2026-03-01T00:00:00Z",
"redirect_url": "https://mysite.com/thank-you",
"terms_url": "https://mysite.com/terms",
"contact_email": "support@mysite.com",
"refund_days": 14,
"show_discount_field": true,
"delegable": true
}'

Response

Success Response (201)

Returns the created product with its empty variants array and all fields.

{
"id": "0632bef5-c308-42cd-9cba-89a7a4f722bb",
"status": "published",
"name": "Premium Coffee Beans",
"description": "High-quality arabica coffee beans from Colombia",
"slug": "premium-arabica-coffee",
"image_url": "https://example.com/images/coffee-beans.jpg",
"checkout_url": "https://cart.easy.tools/checkout/0632bef5-c308-42cd-9cba-89a7a4f722bb",
"currency": "usd",
"file": null,
"files": [],
"active_from": "2026-02-01T00:00:00+00:00",
"active_until": "2026-03-01T00:00:00+00:00",
"show_active_until_counter": null,
"redirect_url": "https://mysite.com/thank-you",
"redirect_time": null,
"add_redirect_params": null,
"webhook_url": null,
"terms_url": "https://mysite.com/terms",
"policy_url": null,
"contact_email": "support@mysite.com",
"refund_days": 14,
"delegable": true,
"show_discount_field": true,
"hide_tax_id_field": false,
"require_tax_id": false,
"photo_zoomable": false,
"show_confetti": false,
"generate_qr_code": false,
"variants": []
}

Response Fields

See Get Product for a complete list of response fields.

Error Responses

Validation Error (422 Unprocessable Entity)

{
"message": "The given data was invalid.",
"errors": {
"name": [
"The name field is required."
],
"status": [
"The status field must be one of: draft, published."
],
"currency": [
"The currency field must be exactly 3 characters."
]
}
}

Slug validation errors:

{
"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 status is published and the store has no active Easytools plan. No product is created. Send status: draft instead, or activate a plan and retry.

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"
}