Product Management
Complete guide to product operations including CRUD operations, images, videos, reviews, bundles, and variants using the REST API.
Products
List All Products
Retrieve paginated list of products.
Endpoint:
GET /api/productsQuery Parameters:
page- Page number (default: 1)limit- Results per page (default: 15)sort- Sort field (default: id)order- Sort order (asc/desc)search- Search termcategory_id- Filter by category
:::tabs
== cURL
curl -X GET "https://your-domain.com/api/products?page=1&limit=10" \
-H "Content-Type: application/json"== Node.js
const params = new URLSearchParams({
page: 1,
limit: 10
});
const response = await fetch(`https://your-domain.com/api/products?${params}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const products = await response.json();
console.log(products);== Python
import requests
params = {
'page': 1,
'limit': 10
}
response = requests.get(
'https://your-domain.com/api/products',
headers={'Content-Type': 'application/json'},
params=params
)
products = response.json()
print(products):::
Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/products",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/products/1",
"@type": "Product",
"id": 1,
"name": "Premium T-Shirt",
"slug": "premium-t-shirt",
"description": "High quality cotton t-shirt",
"short_description": "Premium quality tee",
"sku": "TSHIRT-001",
"price": 29.99,
"cost": 10.00,
"weight": 0.5,
"status": 1,
"visibility": "visible",
"type": "simple",
"url_key": "premium-t-shirt",
"meta_title": "Premium T-Shirt",
"meta_description": "Best quality t-shirt",
"created_at": "2024-01-10T10:00:00Z"
}
],
"hydra:view": {
"@id": "/api/products?page=1",
"@type": "hydra:PartialCollectionView",
"hydra:first": "/api/products?page=1",
"hydra:last": "/api/products?page=5",
"hydra:next": "/api/products?page=2"
},
"hydra:totalItems": 45
}Get Product Details
Retrieve detailed information for a specific product.
Endpoint:
GET /api/products/{id}:::tabs
== cURL
curl -X GET "https://your-domain.com/api/products/1" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/products/1', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const product = await response.json();
console.log(product);== Python
import requests
response = requests.get(
'https://your-domain.com/api/products/1',
headers={'Content-Type': 'application/json'}
)
product = response.json()
print(product):::
Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/products/1",
"@type": "Product",
"id": 1,
"name": "Premium T-Shirt",
"slug": "premium-t-shirt",
"description": "Crafted from 100% organic cotton, this premium t-shirt offers comfort and style.",
"short_description": "High quality cotton t-shirt",
"sku": "TSHIRT-001",
"price": 29.99,
"original_price": 39.99,
"cost": 10.00,
"weight": 0.5,
"status": 1,
"visibility": "visible",
"type": "simple",
"url_key": "premium-t-shirt",
"images": [
{
"id": 10,
"url": "https://cdn.example.com/products/tshirt-1.jpg",
"alt": "Front view",
"position": 0
}
],
"attributes": [
{
"id": 1,
"code": "color",
"label": "Color",
"value": "Blue"
},
{
"id": 2,
"code": "size",
"label": "Size",
"value": "M"
}
],
"categories": [
{
"id": 3,
"name": "Clothing",
"slug": "clothing"
}
],
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-20T10:00:00Z"
}Create Product
Create a new product in the catalog.
Endpoint:
POST /api/products:::tabs
== cURL
curl -X POST "https://your-domain.com/api/products" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "New Product",
"slug": "new-product",
"type": "simple",
"sku": "PROD-001",
"description": "Product description",
"short_description": "Short desc",
"price": 49.99,
"cost": 20.00,
"weight": 1.0,
"status": 1,
"visibility": "visible"
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'New Product',
slug: 'new-product',
type: 'simple',
sku: 'PROD-001',
description: 'Product description',
short_description: 'Short desc',
price: 49.99,
cost: 20.00,
weight: 1.0,
status: 1,
visibility: 'visible'
})
});
const product = await response.json();
console.log(product);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.post(
'https://your-domain.com/api/products',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'name': 'New Product',
'slug': 'new-product',
'type': 'simple',
'sku': 'PROD-001',
'description': 'Product description',
'short_description': 'Short desc',
'price': 49.99,
'cost': 20.00,
'weight': 1.0,
'status': 1,
'visibility': 'visible'
}
)
product = response.json()
print(product):::
Response (201 Created):
{
"@context": "/api/contexts/Product",
"@id": "/api/products/50",
"@type": "Product",
"id": 50,
"name": "New Product",
"slug": "new-product",
"sku": "PROD-001",
"price": 49.99,
"cost": 20.00,
"status": 1,
"created_at": "2024-01-20T11:00:00Z"
}Update Product
Update an existing product.
Endpoint:
PATCH /api/products/{id}:::tabs
== cURL
curl -X PATCH "https://your-domain.com/api/products/1" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Product Name",
"price": 34.99
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products/1', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Updated Product Name',
price: 34.99
})
});
const product = await response.json();
console.log(product);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.patch(
'https://your-domain.com/api/products/1',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'name': 'Updated Product Name',
'price': 34.99
}
)
product = response.json()
print(product):::
Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/products/1",
"@type": "Product",
"id": 1,
"name": "Updated Product Name",
"price": 34.99,
"updated_at": "2024-01-20T11:30:00Z"
}Delete Product
Delete a product from the catalog.
Endpoint:
DELETE /api/products/{id}:::tabs
== cURL
curl -X DELETE "https://your-domain.com/api/products/1" \
-H "Authorization: Bearer ADMIN_TOKEN"== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products/1', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('Product deleted');== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.delete(
'https://your-domain.com/api/products/1',
headers={'Authorization': f'Bearer {token}'}
)
print('Product deleted'):::
Response (204 No Content):
[Empty response body]Product Images
Add Product Image
Upload and add an image to a product.
Endpoint:
POST /api/product_images:::tabs
== cURL
curl -X POST "https://your-domain.com/api/product_images" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-F "product_id=1" \
-F "alt=Front view" \
-F "position=0" \
-F "image=@/path/to/image.jpg"== Node.js
const fs = require('fs');
const FormData = require('form-data');
const token = 'ADMIN_TOKEN';
const form = new FormData();
form.append('product_id', 1);
form.append('alt', 'Front view');
form.append('position', 0);
form.append('image', fs.createReadStream('/path/to/image.jpg'));
const response = await fetch('https://your-domain.com/api/product_images', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
...form.getHeaders()
},
body: form
});
const image = await response.json();
console.log(image);== Python
import requests
token = 'ADMIN_TOKEN'
with open('/path/to/image.jpg', 'rb') as image_file:
files = {'image': image_file}
data = {
'product_id': 1,
'alt': 'Front view',
'position': 0
}
response = requests.post(
'https://your-domain.com/api/product_images',
headers={'Authorization': f'Bearer {token}'},
files=files,
data=data
)
image = response.json()
print(image):::
Response (201 Created):
{
"@context": "/api/contexts/ProductImage",
"@id": "/api/product_images/10",
"@type": "ProductImage",
"id": 10,
"product_id": 1,
"url": "https://cdn.example.com/products/image-10.jpg",
"alt": "Front view",
"position": 0,
"created_at": "2024-01-20T11:45:00Z"
}Delete Product Image
Remove an image from a product.
Endpoint:
DELETE /api/product_images/{id}:::tabs
== cURL
curl -X DELETE "https://your-domain.com/api/product_images/10" \
-H "Authorization: Bearer ADMIN_TOKEN"== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/product_images/10', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('Image deleted');== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.delete(
'https://your-domain.com/api/product_images/10',
headers={'Authorization': f'Bearer {token}'}
)
print('Image deleted'):::
Response (204 No Content):
[Empty response body]Product Videos
Add Product Video
Attach a video to a product.
Endpoint:
POST /api/product_videos:::tabs
== cURL
curl -X POST "https://your-domain.com/api/product_videos" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product_id": 1,
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"type": "youtube",
"title": "Product Demo"
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/product_videos', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
product_id: 1,
url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
type: 'youtube',
title: 'Product Demo'
})
});
const video = await response.json();
console.log(video);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.post(
'https://your-domain.com/api/product_videos',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'product_id': 1,
'url': 'https://youtube.com/watch?v=dQw4w9WgXcQ',
'type': 'youtube',
'title': 'Product Demo'
}
)
video = response.json()
print(video):::
Response (201 Created):
{
"@context": "/api/contexts/ProductVideo",
"@id": "/api/product_videos/5",
"@type": "ProductVideo",
"id": 5,
"product_id": 1,
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"type": "youtube",
"title": "Product Demo",
"created_at": "2024-01-20T11:50:00Z"
}Product Reviews
List Product Reviews
Retrieve reviews for a product.
Endpoint:
GET /api/product_reviews?product_id={product_id}:::tabs
== cURL
curl -X GET "https://your-domain.com/api/product_reviews?product_id=1" \
-H "Content-Type: application/json"== Node.js
const params = new URLSearchParams({
product_id: 1
});
const response = await fetch(`https://your-domain.com/api/product_reviews?${params}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const reviews = await response.json();
console.log(reviews);== Python
import requests
params = {'product_id': 1}
response = requests.get(
'https://your-domain.com/api/product_reviews',
headers={'Content-Type': 'application/json'},
params=params
)
reviews = response.json()
print(reviews):::
Response (200 OK):
{
"@context": "/api/contexts/ProductReview",
"@id": "/api/product_reviews",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/product_reviews/1",
"@type": "ProductReview",
"id": 1,
"product_id": 1,
"customer_id": 5,
"title": "Excellent Quality!",
"comment": "Best t-shirt I've ever purchased",
"rating": 5,
"status": "approved",
"created_at": "2024-01-15T10:00:00Z"
}
],
"hydra:totalItems": 12
}Create Product Review
Submit a review for a product.
Endpoint:
POST /api/product_reviews:::tabs
== cURL
curl -X POST "https://your-domain.com/api/product_reviews" \
-H "Authorization: Bearer CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product_id": 1,
"title": "Great Product",
"comment": "Very satisfied with this purchase",
"rating": 5
}'== Node.js
const token = 'CUSTOMER_TOKEN';
const response = await fetch('https://your-domain.com/api/product_reviews', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
product_id: 1,
title: 'Great Product',
comment: 'Very satisfied with this purchase',
rating: 5
})
});
const review = await response.json();
console.log(review);== Python
import requests
token = 'CUSTOMER_TOKEN'
response = requests.post(
'https://your-domain.com/api/product_reviews',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'product_id': 1,
'title': 'Great Product',
'comment': 'Very satisfied with this purchase',
'rating': 5
}
)
review = response.json()
print(review):::
Response (201 Created):
{
"@context": "/api/contexts/ProductReview",
"@id": "/api/product_reviews/15",
"@type": "ProductReview",
"id": 15,
"product_id": 1,
"customer_id": 10,
"title": "Great Product",
"comment": "Very satisfied with this purchase",
"rating": 5,
"status": "pending",
"created_at": "2024-01-20T12:00:00Z"
}Product Bundles
List Product Bundles
Get bundle products with their children items.
Endpoint:
GET /api/product_bundles:::tabs
== cURL
curl -X GET "https://your-domain.com/api/product_bundles?page=1" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/product_bundles?page=1', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const bundles = await response.json();
console.log(bundles);== Python
import requests
response = requests.get(
'https://your-domain.com/api/product_bundles?page=1',
headers={'Content-Type': 'application/json'}
)
bundles = response.json()
print(bundles):::
Response (200 OK):
{
"@context": "/api/contexts/ProductBundle",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/products/20",
"@type": "Product",
"id": 20,
"name": "Premium Bundle",
"type": "bundle",
"price": 99.99,
"bundle_items": [
{
"id": 1,
"product_id": 1,
"quantity": 2
},
{
"id": 2,
"product_id": 5,
"quantity": 1
}
]
}
],
"hydra:totalItems": 3
}Create Bundle Product
Create a new bundle product.
Endpoint:
POST /api/products (with type=bundle):::tabs
== cURL
curl -X POST "https://your-domain.com/api/products" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Bundle Package",
"type": "bundle",
"sku": "BUNDLE-001",
"price": 99.99,
"status": 1,
"bundle_items": [
{
"product_id": 1,
"quantity": 2
},
{
"product_id": 5,
"quantity": 1
}
]
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Bundle Package',
type: 'bundle',
sku: 'BUNDLE-001',
price: 99.99,
status: 1,
bundle_items: [
{
product_id: 1,
quantity: 2
},
{
product_id: 5,
quantity: 1
}
]
})
});
const bundle = await response.json();
console.log(bundle);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.post(
'https://your-domain.com/api/products',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'name': 'Bundle Package',
'type': 'bundle',
'sku': 'BUNDLE-001',
'price': 99.99,
'status': 1,
'bundle_items': [
{'product_id': 1, 'quantity': 2},
{'product_id': 5, 'quantity': 1}
]
}
)
bundle = response.json()
print(bundle):::
Response (201 Created):
{
"@id": "/api/products/20",
"@type": "Product",
"id": 20,
"name": "Bundle Package",
"type": "bundle",
"sku": "BUNDLE-001",
"price": 99.99,
"bundle_items": [
{
"id": 1,
"product_id": 1,
"quantity": 2
}
]
}Grouped & Configurable Products
Create Grouped Product
Create a grouped product linking related products.
Endpoint:
POST /api/products (with type=grouped):::tabs
== cURL
curl -X POST "https://your-domain.com/api/products" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Grouped Product Set",
"type": "grouped",
"sku": "GROUP-001",
"status": 1,
"grouped_products": [1, 2, 3, 4]
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Grouped Product Set',
type: 'grouped',
sku: 'GROUP-001',
status: 1,
grouped_products: [1, 2, 3, 4]
})
});
const grouped = await response.json();
console.log(grouped);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.post(
'https://your-domain.com/api/products',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'name': 'Grouped Product Set',
'type': 'grouped',
'sku': 'GROUP-001',
'status': 1,
'grouped_products': [1, 2, 3, 4]
}
)
grouped = response.json()
print(grouped):::
Response (201 Created):
{
"@id": "/api/products/21",
"@type": "Product",
"id": 21,
"name": "Grouped Product Set",
"type": "grouped",
"sku": "GROUP-001",
"grouped_products": [1, 2, 3, 4]
}Downloadable Products
Create Downloadable Product
Create a product with downloadable files.
Endpoint:
POST /api/products (with type=downloadable):::tabs
== cURL
curl -X POST "https://your-domain.com/api/products" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "E-Book",
"type": "downloadable",
"sku": "EBOOK-001",
"price": 19.99,
"status": 1,
"downloadable_links": [
{
"title": "Main PDF",
"url": "https://cdn.example.com/ebook.pdf"
}
]
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'E-Book',
type: 'downloadable',
sku: 'EBOOK-001',
price: 19.99,
status: 1,
downloadable_links: [
{
title: 'Main PDF',
url: 'https://cdn.example.com/ebook.pdf'
}
]
})
});
const product = await response.json();
console.log(product);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.post(
'https://your-domain.com/api/products',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'name': 'E-Book',
'type': 'downloadable',
'sku': 'EBOOK-001',
'price': 19.99,
'status': 1,
'downloadable_links': [
{'title': 'Main PDF', 'url': 'https://cdn.example.com/ebook.pdf'}
]
}
)
product = response.json()
print(product):::
Response (201 Created):
{
"@id": "/api/products/22",
"@type": "Product",
"id": 22,
"name": "E-Book",
"type": "downloadable",
"sku": "EBOOK-001",
"price": 19.99,
"downloadable_links": [
{
"id": 1,
"title": "Main PDF",
"url": "https://cdn.example.com/ebook.pdf"
}
]
}Product Pricing & Inventory
Update Product Pricing
Update product pricing information.
Endpoint:
PATCH /api/products/{id}:::tabs
== cURL
curl -X PATCH "https://your-domain.com/api/products/1" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"price": 44.99,
"cost": 15.00,
"special_price": 39.99
}'== Node.js
const token = 'ADMIN_TOKEN';
const response = await fetch('https://your-domain.com/api/products/1', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
price: 44.99,
cost: 15.00,
special_price: 39.99
})
});
const product = await response.json();
console.log(product);== Python
import requests
token = 'ADMIN_TOKEN'
response = requests.patch(
'https://your-domain.com/api/products/1',
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
},
json={
'price': 44.99,
'cost': 15.00,
'special_price': 39.99
}
)
product = response.json()
print(product):::
Response (200 OK):
{
"@id": "/api/products/1",
"@type": "Product",
"id": 1,
"price": 44.99,
"cost": 15.00,
"special_price": 39.99,
"updated_at": "2024-01-20T12:15:00Z"
}
