Developer ResourcescatalogProduct
Catalog Product API & Integration Guide
HTTP contracts for catalog product admin and customer/mobile endpoints.
Catalog Product - API & Integration Guide
1. How to Read / Quick Metadata
- Module: Catalog / Product
- Admin auth:
JwtAuthGuard+RoleGuard+@Permissions(Products_*) - Customer/mobile auth: public endpoints (
@Public()) - Surfaces:
- Admin:
/api/admin/products - Customer:
/api/products - Mobile:
/api/mobile/products
- Admin:
Audience: Mobile/web frontend developers Scope: Product discovery, detail endpoints
2. High-Level Overview
Product APIs provide admin lifecycle management and public browse/detail surfaces for published sellable products. Product detail accepts historical slugs and resolves to the current canonical product.
3. Core Concepts and Terminology
- Sellable visibility: customer APIs only return
isSellable=trueandstatus=published. - Canonical slug: current slug returned in payload.
- Historical slug: old slug stored in
product_slug_historyand still resolvable. - Featured list endpoint: curated subset exposed by
GET /products/featured.
4. Route Summary
Admin
| Method | Path | Permission |
|---|---|---|
GET | /api/admin/products | Products_READ |
GET | /api/admin/products/:id | Products_READ |
POST | /api/admin/products | Products_CREATE |
PATCH | /api/admin/products/:id | Products_UPDATE |
DELETE | /api/admin/products/:id | Products_DELETE |
Customer + Mobile
| Method | Path |
|---|---|
GET | /api/products and /api/mobile/products |
GET | /api/products/featured and /api/mobile/products/featured |
GET | /api/products/:slug and /api/mobile/products/:slug |
Route Details
List Products
| Aspect | Details |
|---|---|
| Endpoint | GET /api/products or /api/mobile/products |
| Auth | Public |
| Request | pagination, search, categoryId |
| Response | ResponseDto<ProductDto[]> |
| Errors | - |
Product Detail
| Aspect | Details |
|---|---|
| Endpoint | GET /api/products/:slug or /api/mobile/products/:slug |
| Auth | Public |
| Request | - |
| Response | ResponseDto<ProductDto> |
| Errors | 404 not found |
5. Query Parameters
Admin list (GET /api/admin/products)
- Inherited from
QueryDto:pagination,page,size,search - Product filters:
categoryId,productType,tagId,status,isSellable - Sort:
title | slug | productType | mrp | sp | status | isSellable | createdAt | updatedAt | relevance - Order:
asc | desc
Customer list (GET /api/products)
- Inherited from
QueryDto:pagination,page,size,search - Filters:
categoryId,productType,tagId - Sort:
title | mrp | sp | createdAt | relevance - Order:
asc | desc
Featured list (GET /api/products/featured)
pagination(default true)page(default 1)size(defaults to env-backedCATALOG_FEATURED_DEFAULT_SIZEwhen omitted)
6. Response Shape Examples
Product list item
"
"id": 101,
"mrp": 15000,
"sp": 12000,
"discount": 3000,
"categoryId": 3,
"Product detail response example
"
"id": 101,
"isSellable": true,
"categoryId": 3,
"tags": ["" "id": 7, "name": "Hand Painted", "slug": "hand-painted" ""]
"7. Enums
productStatus(admin flows):draft | published | unlisted | archivedproductType(physical only):thangka | singing_bowl | statue | jewellery- Sort enums follow DTO-level allowlists (admin/customer differ).
8. Integration Diagram
9. Caching
| Prefix | Usage |
|---|---|
catalog:products:list: | customer list cache |
catalog:product:slug: | detail-by-slug cache |
catalog:products:featured: | customer featured list cache |
Write invalidation happens on admin create/update/delete via prefix invalidation.
10. Error Handling
| HTTP | errorCode | Condition |
|---|---|---|
| 400 | PRODUCT_SP_EXCEEDS_MRP | Selling price greater than MRP |
| 400 | PRODUCT_INVALID_STATUS_TRANSITION | Invalid status transition |
| 400 | PRODUCT_CREATE_FAILED | Create returned no row |
| 400 | PRODUCT_INVALID_SORT | Unsupported sort field |
| 404 | PRODUCT_NOT_FOUND | Product missing |
| 404 | PRODUCT_CATEGORY_NOT_FOUND | Category ID missing |
| 404 | PRODUCT_TAG_NOT_FOUND | One or more tags missing |
| 429 | RATE_LIMIT_EXCEEDED | Search/list limiter exceeded |
11. Endpoint Reference + Payload Cheatsheet
11.1 Payload Cheatsheet Table (Every Endpoint)
| Method | Path | Auth / Permission | Request DTO / Params | Success DTO | Notes |
|---|---|---|---|---|---|
| GET | /api/admin/products | Admin + Products_READ | QueryProductsAdminDto "" page?, size?, pagination?, search?, categoryId?, productType?, tagId?, status?, isSellable?, sort?, order? "" | ProductAdminListItemDto[] paginated | Admin product list with filters |
| GET | /api/admin/products/:id | Admin + Products_READ | path: id (int) | ProductAdminDetailDto | Admin product detail with history |
| POST | /api/admin/products | Admin + Products_CREATE | body: CreateProductDto "" title, slug, description?, shortSummary?, productType, delivery, materials, certificate, isMasterGrade, isBestSeller, size, mrp, sp, categoryId, tagIds?, thumbnailUrl?, galleryUrls?, metadata?, mainFileUrl?, previewFileUrl?, attachments?, isSellable?, ageDisclaimer?, status? "" | ProductAdminDetailDto | Creates new product |
| PATCH | /api/admin/products/:id | Admin + Products_UPDATE | path: id (int), body: UpdateProductDto "" title?, slug?, description?, shortSummary?, productType?, delivery?, materials?, certificate?, isMasterGrade?, isBestSeller?, size?, mrp?, sp?, categoryId?, tagIds?, thumbnailUrl?, galleryUrls?, metadata?, mainFileUrl?, previewFileUrl?, attachments?, isSellable?, ageDisclaimer?, status? "" | ProductAdminDetailDto | Updates product |
| DELETE | /api/admin/products/:id | Admin + Products_DELETE | path: id (int) | "" success: true "" | Soft deletes product |
| GET | /api/products | Public | QueryProductsDto "" page?, size?, pagination?, search?, categoryId?, productType?, tagId?, sort?, order? "" | ProductListItemDto[] paginated | Customer product list |
| GET | /api/mobile/products | Public | QueryProductsDto "" page?, size?, pagination?, search?, categoryId?, productType?, tagId?, sort?, order? "" | ProductListItemDto[] paginated | Mobile product list (same as customer) |
| GET | /api/products/featured | Public | QueryFeaturedProductsDto "" page?, size?, pagination? "" | ProductListItemDto[] paginated | Featured products list |
| GET | /api/mobile/products/featured | Public | QueryFeaturedProductsDto "" page?, size?, pagination? "" | ProductListItemDto[] paginated | Mobile featured products |
| GET | /api/products/:slug | Public | path: slug (string) | ProductDetailDto | Product detail by slug (supports historical slugs) |
| GET | /api/mobile/products/:slug | Public | path: slug (string) | ProductDetailDto | Mobile product detail by slug |
11.1.1 Admin List Endpoint Query Variations
| Method | Path | Query Parameters | Notes |
|---|---|---|---|
| GET | /api/admin/products | (no params) | Default: page=1, size=20, sort=createdAt, order=desc |
| GET | /api/admin/products | ?page=2&size=10 | Custom page and size |
| GET | /api/admin/products | ?categoryId=3 | Filter by category |
| GET | /api/admin/products | ?status=published | Filter by status |
| GET | /api/admin/products | ?isSellable=true | Filter sellable products |
| GET | /api/admin/products | ?tagId=7 | Filter by tag |
| GET | /api/admin/products | ?search=tara | Search by title/slug/description |
| GET | /api/admin/products | ?sort=title&order=asc | Sort by title ascending |
| GET | /api/admin/products | ?sort=mrp&order=desc | Sort by MRP descending |
| GET | /api/admin/products | ?status=published&isSellable=true | Combined filters |
11.1.2 Customer/Mobile List Endpoint Query Variations
| Method | Path | Query Parameters | Notes |
|---|---|---|---|
| GET | /api/products | (no params) | Default: page=1, size=20, sort=relevance, order=desc |
| GET | /api/products | ?page=2&size=10 | Custom pagination |
| GET | /api/products | ?categoryId=3 | Filter by category |
| GET | /api/products | ?tagId=7 | Filter by tag |
| GET | /api/products | ?sort=title&order=asc | Sort by title |
| GET | /api/products | ?sort=mrp&order=desc | Sort by MRP descending |
| GET | /api/products | ?sort=sp&order=asc | Sort by selling price ascending |
| GET | /api/products | ?sort=createdAt&order=desc | Sort by creation date |
| GET | /api/products | ?pagination=false | Return all matching records |
11.1.3 Featured Products Query Variations
| Method | Path | Query Parameters | Notes |
|---|---|---|---|
| GET | /api/products/featured | (no params) | Uses default size from env |
| GET | /api/products/featured | ?page=1&size=10 | Custom page/size |
| GET | /api/products/featured | ?pagination=false | All featured products |
| GET | /api/mobile/products/featured | ?size=20 | Mobile featured with size |
11.1.4 Create Product Request Variations
| Method | Path | Request Body | Notes |
|---|
11.1.5 Update Product Request Variations
| Method | Path | Request Body | Notes |
|---|---|---|---|
| PATCH | /api/admin/products/101 | "" "sp": 9000 "" | Update only selling price |
| PATCH | /api/admin/products/101 | "" "status": "published" "" | Publish product |
| PATCH | /api/admin/products/101 | "" "isSellable": false "" | Mark as not sellable |
| PATCH | /api/admin/products/101 | "" "title": "New Title", "slug": "new-slug" "" | Update title and slug |
| PATCH | /api/admin/products/101 | "" "tags": [1,2,3] "" | Update tags |
| PATCH | /api/admin/products/101 | "" "status": "archived" "" | Archive product |
11.1.6 Product Status Flow States
| Status | IsSellable | Next Possible States | Notes |
|---|---|---|---|
draft | false | published, unlisted | Initial state |
published | true | unlisted, archived | Live on storefront |
unlisted | false | published, archived | Hidden but accessible via direct link |
archived | false | - (terminal) | No longer accessible |
11.1.7 Product Type Size Shapes
| Type | Size Shape | Notes |
|---|---|---|
thangka | rectangular with inch.width, inch.height, cm.width, cm.height | Canvas/frame dimensions |
singing_bowl | radius with numeric inch and numeric cm | Single radius value |
statue | radius with numeric inch and numeric cm | Single radius value |
jewellery | circumference with numeric inch and numeric cm | Bangle/bracelet circumference |
11.1.8 Error Response Variations
| HTTP | errorCode | Message | Scenario |
|---|---|---|---|
| 400 | PRODUCT_SP_EXCEEDS_MRP | Selling price cannot exceed MRP. | SP > MRP on create/update |
| 400 | PRODUCT_INVALID_STATUS_TRANSITION | Invalid status transition. | Invalid status change |
| 400 | PRODUCT_CREATE_FAILED | Failed to create product. | Insert returned no row |
| 400 | PRODUCT_INVALID_SORT | Invalid sort field. | Unsupported sort value |
| 400 | PRODUCT_MISSING_REQUIRED_FIELD | Required field is missing. | Title, productType, delivery, materials, certificate, size, mrp, sp, categoryId |
| 404 | PRODUCT_NOT_FOUND | Product not found. | Invalid product ID |
| 404 | PRODUCT_CATEGORY_NOT_FOUND | Category not found. | Invalid categoryId |
| 404 | PRODUCT_TAG_NOT_FOUND | One or more tags not found. | Invalid tag IDs |
| 409 | PRODUCT_SLUG_EXISTS | Product with this slug already exists. | Duplicate slug |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests. | Rate limit exceeded |
11.1.9 Cache Key Patterns
| Cache Key | Pattern | TTL (seconds) | Invalidation |
|---|---|---|---|
| Customer product list | catalog:products:list:pagination:"page"-size:"size"-sort:"sort"-order:"order"-filters... | 300 | Admin create/update/delete |
| Product detail by slug | catalog:product:slug:"slug" | 600 | Admin update/delete |
| Featured products list | catalog:products:featured:pagination:"page"-size:"size" | 300 | Admin create/update/delete featured |
| Admin product list | catalog:products:admin:list:pagination:"page"-size:"size"-filters... | 60 | Admin mutations |
11.1.10 Rate Limit Patterns
| Route Family | Key Pattern | Limit |
|---|---|---|
| Customer list | rl:catalog:products:customer:list-ip:"ip" | 60 req/min |
| Customer detail | rl:catalog:products:customer:detail-ip:"ip" | 120 req/min |
| Featured list | rl:catalog:products:featured-ip:"ip" | 60 req/min |
| Admin list | rl:catalog:products:admin:list-key:"adminId" | 60 req/min |
| Admin mutations | rl:catalog:products:admin:mutate-key:"adminId" | 30 req/min |
11.1.11 DTO Field Reference
CreateProductDto
| Field | Type | Required | Validation | Notes |
|---|---|---|---|---|
| title | string | Yes | 1-200 chars | Product title |
| slug | string | Yes | 1-100 chars, URL-safe | URL slug |
| description | string | No | Max 5000 chars | Full description |
| shortSummary | string | No | Max 500 chars | Brief summary |
| delivery | string | Yes | 1-500 chars, trimmed non-empty | Delivery/shipping information |
| materials | string[] | Yes | Non-empty, unique, trimmed strings | Materials used |
| certificate | string | Yes | 1-255 chars, trimmed non-empty | Certificate identifier |
| isMasterGrade | boolean | Yes | boolean | Master-grade product flag |
| isBestSeller | boolean | Yes | boolean | Bestseller product flag |
| size | object | Yes | Shape must match productType | Physical size object |
| mrp | number | Yes | Positive integer | Maximum retail price (paisa) |
| sp | number | Yes | Positive integer, not more than mrp | Selling price (paisa) |
| categoryId | integer | Yes | Positive | Category reference |
| tagIds | number[] | No | Valid unique positive tag IDs | Tag references |
| thumbnailUrl | string | No | Valid URL | Thumbnail image |
| galleryUrls | string[] | No | Valid URLs | Product gallery images |
| metadata | object | No | JSON object | Product metadata |
| mainFileUrl | string | No | Valid URL | Main downloadable/media file URL |
| previewFileUrl | string | No | Valid URL | Preview file URL |
| attachments | object[] | No | name/url/type fields | Additional asset attachments |
| isSellable | boolean | No | boolean | Sellable visibility |
| ageDisclaimer | string | No | Max 500 chars | Age/legal disclaimer |
| status | enum | No | draft|published|unlisted|archived | Initial status |
UpdateProductDto
| Field | Type | Required | Validation | Notes |
|---|---|---|---|---|
| title | string | No | 1-200 chars | Product title |
| slug | string | No | 1-100 chars, URL-safe | URL slug |
| description | string | No | Max 5000 chars | Full description |
| shortSummary | string | No | Max 500 chars | Brief summary |
| delivery | string | No | 1-500 chars, trimmed non-empty | Delivery/shipping information |
| materials | string[] | No | Non-empty, unique, trimmed strings | Materials used |
| certificate | string | No | 1-255 chars, trimmed non-empty | Certificate identifier |
| isMasterGrade | boolean | No | boolean | Master-grade product flag |
| isBestSeller | boolean | No | boolean | Bestseller product flag |
| size | object | No | Shape must match productType | Physical size object |
| mrp | number | No | Positive integer | Maximum retail price |
| sp | number | No | Positive integer, < not more than mrp | Selling price |
| categoryId | integer | No | Positive | Category reference |
| tagIds | number[] | No | Valid unique positive tag IDs | Tag references |
| thumbnailUrl | string | No | Valid URL | Thumbnail image |
| galleryUrls | string[] | No | Valid URLs | Product gallery images |
| metadata | object | No | JSON object | Product metadata |
| mainFileUrl | string | No | Valid URL | Main downloadable/media file URL |
| previewFileUrl | string | No | Valid URL | Preview file URL |
| attachments | object[] | No | name/url/type fields | Additional asset attachments |
| ageDisclaimer | string | No | Max 500 chars | Age/legal disclaimer |
| status | enum | No | draft|published|unlisted|archived | Product status |
| isSellable | boolean | No | - | Sellable flag |
QueryProductsDto / QueryProductsAdminDto
| Field | Type | Required | Notes |
|---|---|---|---|
| page | number | No | Page number (default 1) |
| size | number | No | Page size (default 20, max 100) |
| pagination | boolean | No | Enable pagination (default true) |
| search | string | No | Search query |
| categoryId | number | No | Filter by category |
| productType | enum | No | Filter by type |
| tagId | number | No | Filter by tag |
| status | enum | No | (admin only) Filter by status |
| isSellable | boolean | No | (admin only) Filter sellable |
| sort | string | No | Sort field |
| order | string | No | Sort order (asc/desc) |
12. Testing Scenarios
12.1 Suggested Test Scenarios
- Admin creates product with all fields, publishes it, and product appears in customer list.
- Product slug changed in admin; old slug still resolves to canonical detail via historical slug fallback.
- Customer list only returns
isSellable=trueandstatus=publishedproducts; draft products hidden. - Customer with search query "tara" returns matching products by title, shortSummary, or description.
- Featured products endpoint returns only active slots with in-window date ranges.
429rate limit exceeded on customer list/search with sliding window Redis keys.
See Also
- Feature Guide: See Catalog Product - Feature List Section 6 (State Models) for product lifecycle diagrams and status transitions.
- Backend Reference: See Catalog Product - Backend Documentation Section 9 for system architecture diagram.