Skip to main content

Products

6 API calls in this section.

Create Product​

Storefront & Commerce / Products & Variants / Products
POST/storefront/products

Creates 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

  • 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.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Body parameters

ParameterTypeDescription
nameobject—
name.enstring—
name.arstring—
name.kustring—
descriptionobject—
description.enstring—
description.arstring—
description.kustring—
slugstring—
pricenumber—
category_idsarray<string>—
brand_idstring—
Show 9 more body fields

Additional body parameters

ParameterTypeDescription
variant_optionsarray<string>—
is_activeboolean—
tagsarray<string>—
has_variantboolean—
use_product_defaultsboolean—
mediaarray<object>—
media.typestring—
media.urlstring—
media.sortOrdernumber—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/storefront/products" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{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}'

Response examples

201Created
Response body
json
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}

Get Products​

Storefront & Commerce / Products & Variants / Products
GET/storefront/products

Retrieves products for the market with KPI stats, server-side sorting, additive legacy filters, and AdvancedDataGrid column filters.

  • Existing params remain supported: search, category_id, brand_id, is_active, include_variants, limit, offset

  • 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.

Query parameters

ParameterTypeDescription
searchstring

Search products by name or description in any language (en/ar/ku)

Example: t-shirt

category_idstring

Filter products by category ID

Example: category-uuid

brand_idstring

Filter products by brand ID

Example: brand-uuid

is_activestring

Filter by active status (true/false). Default: true

Example: true

include_variantsstring

Include product variants in response (true/false). Default: true

Example: true

limitstring

Number of products to return (default: 20)

Example: 20

offsetstring

Number of products to skip for pagination (default: 0)

Example: 0

sort_bystring

Sort field. Allowed: price, stock_quantity, rating, total_reviews, created_at

Example: created_at

sort_orderstring

Sort order: asc or desc. Default: desc asc or desc (default: desc)

Example: desc

column_filtersstring

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 JSON string with supported keys name, slug, price, stock_quantity, category_id, brand_id, has_variant, is_active, rating, created_at

Example: {"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"}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/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=%7B%22name%22%3A%22samsung%22%2C%22price%22%3A%7B%22min%22%3A5000%2C%22max%22%3A20000%7D%2C%22has_variant%22%3A%22true%22%2C%22created_at%22%3A%7B%22from%22%3A%222026-04-01%22%2C%22to%22%3A%222026-04-30%22%7D%2C%22is_active%22%3A%22true%22%7D" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
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}

Get Product​

Storefront & Commerce / Products & Variants / Products
GET/storefront/products/:productId

Read a storefront product’s catalog details before displaying or editing it.

Path parameters

ParameterTypeDescription
productIdRequiredstring

Dynamic path value from the request URL.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/storefront/products/${PRODUCTID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

No saved response example. Use Try it to inspect a staging response.

Get Product Analytics​

Storefront & Commerce / Products & Variants / Products
GET/storefront/products/:productId/analytics

Returns product detail analytics for the tenant market using the storefront insights read model.

  • Required: Valid Bearer token with tenant admin permissions

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.

Path parameters

ParameterTypeDescription
productIdRequiredstring

UUID of the product

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/storefront/products/${PRODUCTID}/analytics" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
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 & Commerce / Products & Variants / Products
PUT/storefront/products/:productId

Change a storefront product’s content, branding, media, pricing or inventory linkage.

Path parameters

ParameterTypeDescription
productIdRequiredstring

Dynamic path value from the request URL.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Body parameters

ParameterTypeDescription
nameobject—
name.enstring—
name.arstring—
name.kustring—
descriptionobject—
description.enstring—
slugstring—
brand_idstring—
variant_optionsarray<string>—
is_activeboolean—
has_variantboolean—
mediaarray<object>—
Show 13 more body fields

Additional body parameters

ParameterTypeDescription
media.typestring—
media.urlstring—
media.sortOrdernumber—
warehouse_item_idstring—
pricenumber—
skustring—
variant_nameobject—
variant_name.enstring—
variant_descriptionobject—
variant_description.enstring—
variant_imagesarray<string>—
variant_attributesobject—
variant_attributes.colorsstring—
Staging
Request
curl
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/storefront/products/${PRODUCTID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{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}'

Response examples

No saved response example. Use Try it to inspect a staging response.

Delete Product​

Storefront & Commerce / Products & Variants / Products
DELETE/storefront/products/:productId

Remove a product from the storefront catalog.

Path parameters

ParameterTypeDescription
productIdRequiredstring

Dynamic path value from the request URL.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/storefront/products/${PRODUCTID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

No saved response example. Use Try it to inspect a staging response.