Products
6 API calls in this section.
Create Product
/storefront/productsCreates a new product with flexible variant option configuration. The has_variant flag controls whether the product is modeled as: - Multi-variant product (has_variant: true): product defines variant options; warehouse fields are optional at product level; variants handle their own warehouse linking/creation. - Simple single-variant product (has_variant: false): backend will auto-create a single primary variant. Exactly one scenario must be provided: - Scenario A (link existing): warehouse_item_id - Scenario B (create new): warehouse_id + location_id + inventory_quantity (and no warehouse_item_id) Rules: - Sending Scenario A and Scenario B fields together returns 400 - If has_variant is false and neither scenario is provided, returns 400 - Scenario B requires permission manage:operations:tenant Authentication: - Required: Valid Bearer token with tenant admin permissions Required Fields: - name: Multi-language product name object - description: Multi-language product description object - price: Product base price (required, >= 0). Used as fallback when variant has no price. Optional Fields (common): - category_ids: Array of category IDs the product belongs to (product can be linked to multiple categories) - brand_id: Brand ID for the product - variant_options: Array of variant option type names that variants must provide values for (only meaningful when has_variant is true) - is_active: Boolean to enable/disable the product (default: true) - tags: Array of searchable tags - images: Product-level image URLs used as fallback when variants have no images - media: Optional rich media list. Each item: { "type": "image"|"video", "url": "...", "sortOrder": 0 }. When provided, the legacy images array is auto-derived from image-type media sorted by sortOrder. - has_variant: Boolean flag (default: false) The backend will automatically create a primary variant with: - warehouse_item_id: from Scenario A or Scenario B - name: variant_name if provided, otherwise name - description: variant_description if provided, otherwise description - images: variant_images if provided, otherwise product images - attributes: from variant_attributes if provided Variant Options System (for has_variant: true): - System Options: colors, size, volume, model, weight, material, brand - Custom Options: Tenant-specific options like 'ram', 'storage', 'warranty' - Validation: All variants must provide values for selected options - Aggregation: Available option values are automatically aggregated from variants Example Variant Options: - Electronics: ["colors", "size", "model", "ram", "storage"] - Clothing: ["colors", "size", "material", "fit_type"] - Food: ["flavor", "size", "packaging", "organic"] Features: - Multi-language support (en, ar, ku) - Flexible variant option selection - Automatic validation of variant attributes - Option value aggregation for filtering - System and custom option support Slug uniqueness (DB enforced): slug must be unique per market (trimmed, case-insensitive). Duplicate slug returns 409 Conflict with a localized message to choose a different slug. Variant slugs are unique per product the same way.
1curl --request POST "$ONDI_BASE_URL/storefront/products" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --data '{5 "name": {6 "en": "MacBook Pro Laptop",7 "ar": "لابتوب ماك بوك برو",8 "ku": "لابتۆپی ماک بوک پرۆ"9 },10 "description": {11 "en": "High-performance laptop for professionals",12 "ar": "لابتوب عالي الأداء للمحترفين",13 "ku": "لابتۆپی بەرزی کارایی بۆ پیشەییەکان"14 },15 "slug": "macbook-pro-laptop",16 "price": 1999.99,17 "category_ids": [18 "electronics-category-id"19 ],20 "brand_id": "brand-uuid",21 "variant_options": [22 "colors",23 "size",24 "model",25 "ram"26 ],27 "is_active": true,28 "tags": [29 "laptop",30 "professional",31 "apple"32 ],33 "has_variant": true,34 "use_product_defaults": false,35 "media": [36 {37 "type": "image",38 "url": "https://cdn.example.com/products/macbook-pro/main.jpg",39 "sortOrder": 040 },41 {42 "type": "video",43 "url": "https://cdn.example.com/products/macbook-pro/demo.mp4",44 "sortOrder": 145 },46 {47 "type": "image",48 "url": "https://cdn.example.com/products/macbook-pro/alt-1.jpg",49 "sortOrder": 250 }51 ]52}'1{2 "name": {3 "en": "MacBook Pro Laptop",4 "ar": "لابتوب ماك بوك برو",5 "ku": "لابتۆپی ماک بوک پرۆ"6 },7 "description": {8 "en": "High-performance laptop for professionals",9 "ar": "لابتوب عالي الأداء للمحترفين",10 "ku": "لابتۆپی بەرزی کارایی بۆ پیشەییەکان"11 },12 "slug": "macbook-pro-laptop",13 "price": 1999.99,14 "category_ids": [15 "electronics-category-id"16 ],17 "brand_id": "brand-uuid",18 "variant_options": [19 "colors",20 "size",21 "model",22 "ram"23 ],24 "is_active": true,25 "tags": [26 "laptop",27 "professional",28 "apple"29 ],30 "has_variant": true,31 "use_product_defaults": false,32 "media": [33 {34 "type": "image",35 "url": "https://cdn.example.com/products/macbook-pro/main.jpg",36 "sortOrder": 037 },38 {39 "type": "video",40 "url": "https://cdn.example.com/products/macbook-pro/demo.mp4",41 "sortOrder": 142 },43 {44 "type": "image",45 "url": "https://cdn.example.com/products/macbook-pro/alt-1.jpg",46 "sortOrder": 247 }48 ]49}Request body fields
nameExampleExample field from the request body.
name.enExampleExample field from the request body.
name.arExampleExample field from the request body.
name.kuExampleExample field from the request body.
descriptionExampleExample field from the request body.
description.enExampleExample field from the request body.
description.arExampleExample field from the request body.
description.kuExampleExample field from the request body.
slugExampleExample field from the request body.
priceExampleExample field from the request body.
category_idsExampleExample field from the request body.
brand_idExampleExample field from the request body.
variant_optionsExampleExample field from the request body.
is_activeExampleExample field from the request body.
tagsExampleExample field from the request body.
has_variantExampleExample field from the request body.
use_product_defaultsExampleExample field from the request body.
mediaExampleExample field from the request body.
media.typeExampleExample field from the request body.
media.urlExampleExample field from the request body.
media.sortOrderExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Product created successfully",4 "product": {5 "id": "product-uuid",6 "market_id": "market-uuid",7 "brand_id": "brand-uuid",8 "slug": "macbook-pro-laptop",9 "price": 1999.99,10 "name": {11 "en": "MacBook Pro Laptop",12 "ar": "لابتوب ماك بوك برو",13 "ku": "لابتۆپی ماک بوک پرۆ"14 },15 "description": {16 "en": "High-performance laptop for professionals",17 "ar": "لابتوب عالي الأداء للمحترفين",18 "ku": "لابتۆپی بەرزی کارایی بۆ پیشەییەکان"19 },20 "is_active": true,21 "tags": [22 "laptop",23 "professional",24 "apple"25 ],26 "has_variant": true,27 "use_product_defaults": false,28 "images": [29 "https://cdn.example.com/products/macbook-pro/main.jpg",30 "https://cdn.example.com/products/macbook-pro/alt-1.jpg"31 ],32 "media": [33 {34 "type": "image",35 "url": "https://cdn.example.com/products/macbook-pro/main.jpg",36 "sortOrder": 037 },38 {39 "type": "video",40 "url": "https://cdn.example.com/products/macbook-pro/demo.mp4",41 "sortOrder": 142 },43 {44 "type": "image",45 "url": "https://cdn.example.com/products/macbook-pro/alt-1.jpg",46 "sortOrder": 247 }48 ],49 "variant_options": [50 "colors",51 "size",52 "model",53 "ram"54 ],55 "available_option_values": {},56 "categories": [57 {58 "id": "electronics-category-id",59 "name": {60 "en": "Electronics",61 "ar": "إلكترونيات",62 "ku": "ئەلیکترۆنیات"63 }64 }65 ],66 "stock_quantity": 0,67 "created_at": "2024-07-20T10:00:00Z",68 "updated_at": "2024-07-20T10:00:00Z"69 }70}1{2 "success": false,3 "message": "Validation failed",4 "errors": [5 {6 "field": "name",7 "message": "Name is required"8 }9 ]10}1{2 "success": false,3 "message": "This product URL slug is already used in your store. Please choose a different slug."4}Get Products
/storefront/products?search=t-shirt&category_id=category-uuid&brand_id=brand-uuid&is_active=true&include_variants=true&limit=20&offset=0&sort_by=created_at&sort_order=desc&column_filters={"name":"samsung","slug":"sam","price":{"min":5000,"max":20000},"stock_quantity":{"min":0,"max":100},"category_id":"uuid","brand_id":"uuid","has_variant":"true","is_active":"true","rating":{"min":3,"max":5},"created_at":{"from":"2026-04-01","to":"2026-04-30"}}Retrieves products for the market with KPI stats, server-side sorting, additive legacy filters, and AdvancedDataGrid column filters. Query Parameters: - Existing params remain supported: search, category_id, brand_id, is_active, include_variants, limit, offset - sort_by: price, stock_quantity, rating, total_reviews, created_at - sort_order: asc or desc (default: desc) - column_filters: JSON string with supported keys name, slug, price, stock_quantity, category_id, brand_id, has_variant, is_active, rating, created_at - Numeric range filters use { "min": number, "max": number } - Date range filters use { "from": "YYYY-MM-DD", "to": "YYYY-MM-DD" } - Boolean filters use string values "true" or "false" Stats: - totalProducts: total products in market - activeProducts: products where is_active = true - lowStockItems: products where stock_quantity < 10 - topSelling: English name of the top-selling product in this market Notes: - column_filters are AND-combined with each other and with top-level filters. - Legacy numeric string ranges like "5000,20000" are still accepted for backward compatibility. - Legacy single-date created_at strings are still accepted and treated as one-day ranges. - rating and total_reviews come from actual approved review data. - stats are market-global and are not affected by filters, sorting, or pagination.
1curl --request GET "$ONDI_BASE_URL/storefront/products?search=t-shirt&category_id=category-uuid&brand_id=brand-uuid&is_active=true&include_variants=true&limit=20&offset=0&sort_by=created_at&sort_order=desc&column_filters={"name":"samsung","slug":"sam","price":{"min":5000,"max":20000},"stock_quantity":{"min":0,"max":100},"category_id":"uuid","brand_id":"uuid","has_variant":"true","is_active":"true","rating":{"min":3,"max":5},"created_at":{"from":"2026-04-01","to":"2026-04-30"}}" \2 --header "Authorization: Bearer {{access_token}}"Query parameters
searchOptionalt-shirt
Search products by name or description in any language (en/ar/ku)
category_idOptionalcategory-uuid
Filter products by category ID
brand_idOptionalbrand-uuid
Filter products by brand ID
is_activeOptionaltrue
Filter by active status (true/false). Default: true
include_variantsOptionaltrue
Include product variants in response (true/false). Default: true
limitOptional20
Number of products to return (default: 20)
offsetOptional0
Number of products to skip for pagination (default: 0)
sort_byOptionalcreated_at
Sort field. Allowed: price, stock_quantity, rating, total_reviews, created_at
sort_orderOptionaldesc
Sort order: asc or desc. Default: desc
column_filtersOptional{"name":"samsung","slug":"sam","price":{"min":5000,"max":20000},"stock_quantity":{"min":0,"max":100},"category_id":"uuid","brand_id":"uuid","has_variant":"true","is_active":"true","rating":{"min":3,"max":5},"created_at":{"from":"2026-04-01","to":"2026-04-30"}}
Advanced column filters JSON. Numeric ranges use min/max. Date ranges use from/to. Boolean filters use string true/false. Supported keys: name, slug, price, stock_quantity, category_id, brand_id, has_variant, is_active, rating, created_at
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "message": "Products retrieved successfully",4 "products": [5 {6 "id": "product-uuid-1",7 "market_id": "market-uuid",8 "brand_id": "brand-uuid",9 "slug": "aero-pure-3000",10 "price": 12500,11 "name": {12 "en": "Aero-Pure 3000"13 },14 "is_active": true,15 "stock_quantity": 8,16 "rating": 4.6,17 "total_reviews": 23,18 "created_at": "2026-04-01T10:00:00Z",19 "updated_at": "2026-04-02T10:00:00Z"20 }21 ],22 "pagination": {23 "limit": 20,24 "offset": 0,25 "total": 458226 },27 "stats": {28 "totalProducts": 4582,29 "activeProducts": 4210,30 "lowStockItems": 24,31 "topSelling": "Aero-Pure 3000"32 }33}1{2 "success": true,3 "message": "Products retrieved successfully",4 "products": [],5 "pagination": {6 "limit": 20,7 "offset": 0,8 "total": 09 },10 "stats": {11 "totalProducts": 0,12 "activeProducts": 0,13 "lowStockItems": 0,14 "topSelling": ""15 }16}Get Product
/storefront/products/:productId1curl --request GET "$ONDI_BASE_URL/storefront/products/:productId" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
productIdRequiredHeaders
AuthorizationOptionalBearer {{access_token}}
Responses
No response example is available for this endpoint yet.
Get Product Analytics
/storefront/products/:productId/analyticsReturns product detail analytics for the tenant market using the storefront insights read model. Authentication: - Required: Valid Bearer token with tenant admin permissions Path Parameters: - productId: UUID of the product Read Model: - Current totals/trends come from storefront_product_insights_current - Monthly chart data comes from storefront_product_insights_daily - Engagement events can be fed by storefront_product_events Response Metrics: - total_sales: Total sold quantity for the product - total_views: Current product view count - total_likes: Current like / wishlist count - add_to_basket: Add-to-basket total - conversion_rate: (total_sales / total_views) * 100 when views exist, otherwise 0 - sales_trend, views_trend, likes_trend, basket_trend: Percentage change vs previous 30-day window - monthly_sales: Sold quantity for the last 12 calendar months in chronological order - month_labels: Month labels aligned with monthly_sales - total_revenue, monthly_revenue, avg_rating, total_reviews, stats_last_updated: extra fields currently available Notes: - If the new insight tables are not deployed yet, the API falls back to the previous live calculation path.
1curl --request GET "$ONDI_BASE_URL/storefront/products/:productId/analytics" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
productIdRequiredHeaders
AuthorizationOptionalBearer {{access_token}}
Responses
1{2 "success": true,3 "analytics": {4 "total_sales": 1248,5 "total_views": 0,6 "total_likes": 312,7 "add_to_basket": 0,8 "conversion_rate": 0,9 "sales_trend": 12.5,10 "views_trend": 0,11 "likes_trend": 0,12 "basket_trend": 0,13 "monthly_sales": [14 65,15 85,16 72,17 95,18 88,19 110,20 102,21 125,22 118,23 135,24 128,25 14826 ],27 "month_labels": [28 "Jan",29 "Feb",30 "Mar",31 "Apr",32 "May",33 "Jun",34 "Jul",35 "Aug",36 "Sep",37 "Oct",38 "Nov",39 "Dec"40 ],41 "total_revenue": 52400,42 "monthly_revenue": [43 2700,44 3400,45 2950,46 4200,47 3980,48 4700,49 4520,50 5300,51 5010,52 5900,53 5650,54 609055 ],56 "avg_rating": 4.6,57 "total_reviews": 23,58 "stats_last_updated": "2026-04-23T08:00:00Z"59 }60}Update Product
/storefront/products/:productId1curl --request PUT "$ONDI_BASE_URL/storefront/products/:productId" \2 --header "Authorization: Bearer {{access_token}}" \3 --header "Content-Type: application/json" \4 --data '{5 "name": {6 "en": "Updated MacBook Pro",7 "ar": "ماك بوك برو محدث",8 "ku": "ماک بوک پرۆی نوێکراوە"9 },10 "description": {11 "en": "Latest generation MacBook Pro with enhanced performance"12 },13 "slug": "updated-macbook-pro",14 "brand_id": "brand-uuid",15 "variant_options": [16 "colors",17 "size",18 "model",19 "ram",20 "storage"21 ],22 "is_active": true,23 "has_variant": false,24 "media": [25 {26 "type": "image",27 "url": "https://cdn.example.com/products/macbook-pro/main-updated.jpg",28 "sortOrder": 029 },30 {31 "type": "video",32 "url": "https://cdn.example.com/products/macbook-pro/promo.mp4",33 "sortOrder": 134 }35 ],36 "warehouse_item_id": "warehouse-item-simple-macbook",37 "price": 1999.99,38 "sku": "MBP-SIMPLE-BASE",39 "variant_name": {40 "en": "MacBook Pro Base Model"41 },42 "variant_description": {43 "en": "Base configuration automatically managed as a single variant"44 },45 "variant_images": [46 "https://cdn.example.com/products/macbook-pro/variant-base.jpg"47 ],48 "variant_attributes": {49 "colors": "Space Gray"50 }51}'1{2 "name": {3 "en": "Updated MacBook Pro",4 "ar": "ماك بوك برو محدث",5 "ku": "ماک بوک پرۆی نوێکراوە"6 },7 "description": {8 "en": "Latest generation MacBook Pro with enhanced performance"9 },10 "slug": "updated-macbook-pro",11 "brand_id": "brand-uuid",12 "variant_options": [13 "colors",14 "size",15 "model",16 "ram",17 "storage"18 ],19 "is_active": true,20 "has_variant": false,21 "media": [22 {23 "type": "image",24 "url": "https://cdn.example.com/products/macbook-pro/main-updated.jpg",25 "sortOrder": 026 },27 {28 "type": "video",29 "url": "https://cdn.example.com/products/macbook-pro/promo.mp4",30 "sortOrder": 131 }32 ],33 "warehouse_item_id": "warehouse-item-simple-macbook",34 "price": 1999.99,35 "sku": "MBP-SIMPLE-BASE",36 "variant_name": {37 "en": "MacBook Pro Base Model"38 },39 "variant_description": {40 "en": "Base configuration automatically managed as a single variant"41 },42 "variant_images": [43 "https://cdn.example.com/products/macbook-pro/variant-base.jpg"44 ],45 "variant_attributes": {46 "colors": "Space Gray"47 }48}Path parameters
productIdRequiredRequest body fields
nameExampleExample field from the request body.
name.enExampleExample field from the request body.
name.arExampleExample field from the request body.
name.kuExampleExample field from the request body.
descriptionExampleExample field from the request body.
description.enExampleExample field from the request body.
slugExampleExample field from the request body.
brand_idExampleExample field from the request body.
variant_optionsExampleExample field from the request body.
is_activeExampleExample field from the request body.
has_variantExampleExample field from the request body.
mediaExampleExample field from the request body.
media.typeExampleExample field from the request body.
media.urlExampleExample field from the request body.
media.sortOrderExampleExample field from the request body.
warehouse_item_idExampleExample field from the request body.
priceExampleExample field from the request body.
skuExampleExample field from the request body.
variant_nameExampleExample field from the request body.
variant_name.enExampleExample field from the request body.
variant_descriptionExampleExample field from the request body.
variant_description.enExampleExample field from the request body.
variant_imagesExampleExample field from the request body.
variant_attributesExampleExample field from the request body.
variant_attributes.colorsExampleExample field from the request body.
Headers
AuthorizationOptionalBearer {{access_token}}
Responses
No response example is available for this endpoint yet.
Delete Product
/storefront/products/:productId1curl --request DELETE "$ONDI_BASE_URL/storefront/products/:productId" \2 --header "Authorization: Bearer {{access_token}}"Path parameters
productIdRequiredHeaders
AuthorizationOptionalBearer {{access_token}}
Responses
No response example is available for this endpoint yet.