API docs: Products
List products
/api/v1/productsproducts:readReturns physical and digital products, newest first. Services and events have their own endpoints: Services and Events. Deleted products are never returned. List entries don't include description, variants, or combinations; retrieve the product for those.
Query parameters
| Parameter | Description |
|---|---|
statusstring | active, inactive, or incomplete. |
updated_sincedate | ISO 8601 date or date-time. Covers creation and edits made in the dashboard's product editor - stock changes from sales and quick status toggles don't count as updates. |
categorystring | Only listings in the category with this code. |
qstring | Search product name or code. |
limitinteger | 1–100, default 25. |
cursorstring | The next_cursor from the previous page. |
curl "https://e2c.store/api/v1/products?status=active&q=tee" \
-H "Authorization: Bearer $E2C_API_KEY"{
"data": [
{
"code": "linen-tee",
"name": "Linen Tee",
"sku": "LT-001",
"brand": "Maple & Thread",
"category": { "code": "tops", "name": "Tops" },
"status": "active",
"currency": "CAD",
"price": 19.99,
"compare_at_price": 24.99,
"short_description": "Breathable everyday tee.",
"created_at": "2026-08-12T16:20:00Z",
"updated_at": "2026-09-03T10:45:00Z",
"stock": 42,
"is_digital": false,
"gtin": "",
"mpn": "",
"condition": "new",
"condition_other": "",
"local_pickup": false
}
],
"has_more": false,
"next_cursor": null
}is_digital is true for downloadable products. code identifies a product everywhere in the API and is unique within your store. You can edit a product's code in the dashboard, so if you store codes in another system, update them when you rename one. compare_at_price is the struck-through "was" price, or null when none is set. condition is one of new, refurbished, used_like_new, used_very_good, used_good, used_acceptable, other, or null for digital products; condition_other describes it when it's other. local_pickup is true when buyers can pick the product up.
Retrieve a product
/api/v1/products/{code}products:readReturns one product with its full description, shipping options, variants, and variant combinations (price and stock for each combination). Look it up by its product code - the same code shown in your dashboard and in the product's store URL.
curl "https://e2c.store/api/v1/products/linen-tee" \
-H "Authorization: Bearer $E2C_API_KEY"{
"data": {
"code": "linen-tee",
"name": "Linen Tee",
"sku": "LT-001",
"brand": "Maple & Thread",
"category": { "code": "tops", "name": "Tops" },
"status": "active",
"currency": "CAD",
"price": 19.99,
"compare_at_price": 24.99,
"short_description": "Breathable everyday tee.",
"created_at": "2026-08-12T16:20:00Z",
"updated_at": "2026-09-03T10:45:00Z",
"stock": 42,
"is_digital": false,
"gtin": "",
"mpn": "",
"condition": "new",
"condition_other": "",
"local_pickup": false,
"keywords": ["linen", "summer"],
"description": "<p>Cut from 100% European linen...</p>",
"shipping": [
{ "method": "Standard Shipping", "delivery_time": "7-14 business days", "price": 5.5 },
{ "method": "Express Shipping", "delivery_time": "1-2 business days", "price": 15 }
],
"variants": [
{ "name": "Size", "options": ["S", "M", "L"] },
{ "name": "Color", "options": ["Sand", "Navy"] }
],
"combinations": [
{ "options": ["M", "Navy"], "price": 21.99, "stock": 8 },
{ "options": ["L", "Sand"], "price": null, "stock": 0 }
]
}
}description is the HTML from your product editor. shipping lists the product's shipping options, and is empty for digital products and products sold by local pickup only. A combination's price or stock is null when it isn't set for that combination.
Create a product
/api/v1/productsproducts:writeAdds a physical product. name and price are required; every other field is optional. When you leave out code, one is made from the name, with a number added if it's taken.
New products are active, so buyers need a way to get them: send at least one shipping option or "local_pickup": true. To save a product hidden, send "status": "inactive"; shipping is optional then.
Body fields
| Field | Description |
|---|---|
namestring | Up to 50 characters, plain text. Unique across your products, services, and events. |
codestring | Up to 50 lowercase letters, numbers, and single hyphens, like linen-tee. Used in the product's URL and unique within your store. |
pricenumber | In your store's currency, up to two decimals. |
compare_at_pricenumber | The struck-through "was" price. null or 0 removes it. |
stockinteger | 0–1,000,000. |
statusstring | active or inactive. |
categorystring | A category code. null removes the product from its category. |
skustring | Up to 20 characters. |
brandstring | Up to 20 characters. |
gtinstring | Barcode number (UPC, EAN, or ISBN), up to 20 characters. |
mpnstring | Manufacturer part number, up to 20 characters. |
conditionstring | new, refurbished, used_like_new, used_very_good, used_good, used_acceptable, other. Physical products only. |
condition_otherstring | Up to 20 characters. Required when condition is other. |
short_descriptionstring | Up to 150 characters of plain text, shown near the price. |
descriptionstring | Up to 20,000 characters. Plain text, or simple HTML: p, br, strong, em, u, s, headings, lists, blockquote, and https/mailto links. Other tags are removed but their text is kept, and all attributes except a link's href are dropped. |
keywordsstring[] | Search keywords, up to 100 characters in total. Replaces the existing list; [] clears it. |
shippingobject[] | Up to 3 shipping options, each with method (Standard Shipping, Economy Shipping, Express Shipping, Expedited Shipping, Standard Air Shipping, Standard Sea Shipping, Standard Road Shipping), delivery_time (1-2 business days, 1-7 business days, 7-14 business days, 14-21 business days, 21-28 business days, 1-2 months), and price (0 for free shipping). Each method can appear once, and one must be Standard Shipping. Replaces the existing list; [] removes them all. Physical products only. |
local_pickupboolean | Whether buyers can pick the product up locally. Physical products only. |
curl -X POST "https://e2c.store/api/v1/products" \
-H "Authorization: Bearer $E2C_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Linen Tee", "price": 19.99, "stock": 42, "category": "tops", "shipping": [{ "method": "Standard Shipping", "delivery_time": "7-14 business days", "price": 5.5 }] }'{
"data": {
"code": "linen-tee",
"name": "Linen Tee",
"category": { "code": "tops", "name": "Tops" },
"status": "active",
"price": 19.99,
"stock": 42,
"shipping": [
{ "method": "Standard Shipping", "delivery_time": "7-14 business days", "price": 5.5 }
],
"...": "..."
}
}Returns 201 with the product as Retrieve a product returns it. Images, variants, and digital files are added in the dashboard, so digital products, services, and events can't be created through the API. A store holds at most 100 listings; past that you get 409 limit_reached. A name or code that's already used returns 409 conflict.
Update a product
/api/v1/products/{code}products:writeChanges a physical or digital product. Only the fields you send change. To rename a product's code, send the new one as code; the old code stops working right away.
Body fields
| Field | Description |
|---|---|
namestring | Up to 50 characters, plain text. Unique across your products, services, and events. |
codestring | Up to 50 lowercase letters, numbers, and single hyphens, like linen-tee. Used in the product's URL and unique within your store. |
pricenumber | In your store's currency, up to two decimals. |
compare_at_pricenumber | The struck-through "was" price. null or 0 removes it. |
stockinteger | 0–1,000,000. |
statusstring | active or inactive. |
categorystring | A category code. null removes the product from its category. |
skustring | Up to 20 characters. |
brandstring | Up to 20 characters. |
gtinstring | Barcode number (UPC, EAN, or ISBN), up to 20 characters. |
mpnstring | Manufacturer part number, up to 20 characters. |
conditionstring | new, refurbished, used_like_new, used_very_good, used_good, used_acceptable, other. Physical products only. |
condition_otherstring | Up to 20 characters. Required when condition is other. |
short_descriptionstring | Up to 150 characters of plain text, shown near the price. |
descriptionstring | Up to 20,000 characters. Plain text, or simple HTML: p, br, strong, em, u, s, headings, lists, blockquote, and https/mailto links. Other tags are removed but their text is kept, and all attributes except a link's href are dropped. |
keywordsstring[] | Search keywords, up to 100 characters in total. Replaces the existing list; [] clears it. |
shippingobject[] | Up to 3 shipping options, each with method (Standard Shipping, Economy Shipping, Express Shipping, Expedited Shipping, Standard Air Shipping, Standard Sea Shipping, Standard Road Shipping), delivery_time (1-2 business days, 1-7 business days, 7-14 business days, 14-21 business days, 21-28 business days, 1-2 months), and price (0 for free shipping). Each method can appear once, and one must be Standard Shipping. Replaces the existing list; [] removes them all. Physical products only. |
local_pickupboolean | Whether buyers can pick the product up locally. Physical products only. |
curl -X PATCH "https://e2c.store/api/v1/products/linen-tee" \
-H "Authorization: Bearer $E2C_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "price": 17.99, "compare_at_price": 19.99, "stock": 30 }'{
"data": {
"code": "linen-tee",
"name": "Linen Tee",
"status": "active",
"price": 17.99,
"compare_at_price": 19.99,
"stock": 30,
"...": "..."
}
}Some changes return 409 conflict with a message saying why:
- Leaving an active physical product with no shipping options and no local pickup, whether by setting
statustoactiveor by removing itsshippingorlocal_pickup. - Setting
priceorstockon a product whose variants have their own prices or stock. Change those in the dashboard. - A
nameorcodethat another listing already uses.
Services and events return 404. condition, condition_other, shipping, and local_pickup can't be set on digital products.