6.8 KiB
Products API
Base URL: /api
All responses are wrapped by the global response interceptor:
{
"success": true,
"statusCode": 200,
"path": "/api/products",
"timestamp": "2026-03-25T10:00:00.000Z",
"data": {}
}
Product Model
Each product now supports:
skutitleslugsummarydescriptiontechnicalCodebrandbasePriceUSDsalePriceUSDstockfeaturedtypestatus:draft | published | archivedmainImageUrlimageGalleryUrlsthreeDModelUrlattributes: JSON object for technical specs/featurestags: string arrayaverageRatingreviewsCountcategory
Public Product APIs
GET /api/products
Lists published products for storefront.
Query params:
searchtypecategoryIdbrandattributesas JSON stringtagsas JSON string arrayfeaturedsort:newest | oldest | price_asc | price_desc | popular | top_ratedpagelimit
Optional request header:
x-product-type:Industrial | Automotive
Example:
GET /api/products?search=skf&featured=true&sort=price_asc&page=1&limit=20
x-product-type: Industrial
List response items are intentionally lightweight and include only fields needed for product cards / list pages. The attributes array is limited to the first 2 visible attributes, sorted by displayOrder.
GET /api/products/brands/:brandSlug
Lists published products for one brand by brand slug.
Supports the same query params as GET /api/products:
searchfeaturedsortpagelimit
Optional request header:
x-product-type:Industrial | Automotive
GET /api/products/brands/:brandSlug/filters
Returns available brand page filters relative to the selected brand and current query filters.
Response shape:
categories: available categories with countattributes: available filterable attributes and their values with countstock:inStockandoutOfStock
Optional request header:
x-product-type:Industrial | Automotive
GET /api/products/categories/:categorySlug
Lists published products for one category by category slug.
Supports the same query params as GET /api/products:
searchfeaturedsortpagelimit
Optional request header:
x-product-type:Industrial | Automotive
GET /api/products/categories/:categorySlug/filters
Returns available category page filters relative to the selected category and current query filters.
Response shape:
brands: available brands with countattributes: available filterable attributes and their values with countstock:inStockandoutOfStock
Optional request header:
x-product-type:Industrial | Automotive
GET /api/product/:slug
Returns one published product by slug with category and up to 10 approved reviews.
GET /api/products/:id
Returns one published product with category and up to 10 approved reviews.
GET /api/products/:id/reviews
Returns approved reviews for one published product.
POST /api/products/:id/reviews
Creates a review for a published product. New reviews are stored as pending approval.
Request body:
{
"name": "Ali Rezaei",
"email": "ali@example.com",
"rating": 5,
"title": "Excellent quality",
"comment": "Good quality product with solid packaging."
}
Admin Product APIs
These endpoints require:
- Bearer token
- Admin role
products.managepermission
GET /api/admin/products
Lists all products for admin panel, including drafts and archived items.
Query params:
searchtypestatuscategoryIdbrandattributesas JSON stringtagsas JSON string arrayfeaturedsort:newest | oldest | price_asc | price_desc | popular | top_ratedpagelimit
Optional request header:
x-product-type:Industrial | Automotive
GET /api/admin/products/:id
Returns one product for admin panel.
POST /api/admin/products
Creates a product. Content type: multipart/form-data
Fields:
skutitleslugsummarydescriptiontechnicalCodebrandbasePriceUSDsalePriceUSDstockfeaturedtypestatuscategoryIdattributesas JSON string- each item in
attributescan includedisplayOrder tagsas JSON string arrayexistingMainImageUrlexistingGalleryUrlsas JSON string arrayexistingThreeDModelUrlmainImagefileimagesfilesmodel3dfile
Notes:
mainImageis the primary product image.imagesfills the gallery.model3dis for.glb,.gltf, or other supported 3D assets.- If no new file is uploaded, existing URLs can be sent.
Example multipart fields:
sku=BRG-6006-2RS
title=SKF 6006-2RS Deep Groove Bearing
slug=skf-6006-2rs
summary=Industrial bearing for motors and gearboxes
description=Full product description
technicalCode=SKF-6006
brand=SKF
basePriceUSD=42.5
salePriceUSD=39.99
stock=28
featured=true
type=bearing
status=published
categoryId=<uuid>
attributes={"innerDiameter":"30mm","outerDiameter":"55mm","sealType":"2RS"}
tags=["bearing","skf","industrial"]
PATCH /api/admin/products/:id
Updates a product. Content type: multipart/form-data
Behavior:
- upload new
mainImageto replace the old main image - upload new
imagesto replace the whole gallery - upload new
model3dto replace the old 3D model - send
existingGalleryUrlsto keep only selected old gallery items - send empty
existingMainImageUrlorexistingThreeDModelUrlto clear them
DELETE /api/admin/products/:id
Deletes product row and linked uploaded assets.
Admin Review APIs
GET /api/admin/products/reviews/list
Lists reviews for moderation.
Query params:
productIdisApprovedisPinnedpagelimit
PATCH /api/admin/products/reviews/:reviewId
Approves or pins a review.
Request body:
{
"isApproved": true,
"isPinned": false
}
When approval state changes, averageRating and reviewsCount on the product are recalculated.
DELETE /api/admin/products/reviews/:reviewId
Deletes a review and refreshes product review stats.
Category APIs
Current category endpoints:
POST /api/categoriesGET /api/categoriesGET /api/categories/:idPATCH /api/categories/:idDELETE /api/categories/:id
Category object:
idnameslugtypeparentchildren
Rule:
- child category type must match parent category type
Frontend Integration Notes
- Public storefront should use
/api/products - Admin panel should use
/api/admin/products - Reviews submitted from storefront are pending until approved in admin
attributesandtagsshould be managed as structured JSON on the frontend- Use
mainImageUrl,imageGalleryUrls, andthreeDModelUrlas separate media sections in UI