Zid Docs
Apps
ThemesPayments
Apps
ThemesPayments
Help Center
Slack
  1. Managing Products
  • 🗂️ Overview
  • 🚀 Start Here
  • Create your First App
  • Responses
  • Rate Limiting
  • Authorization
  • Embedded Apps
  • StoreFront Events
  • Zid MUI
  • Zid SDKs
  • Our custom MCP server
  • Merchant APIs
    • Account
      • Me
        • Me
        • Profile
      • Store
        • Store
        • Branding
        • Localization
        • Social
        • Operations
        • Business
        • Upload Logo Image
        • Delete Logo Image
        • Upload Icon Image
        • Delete Icon Image
        • Upload Cover Image
        • Delete Cover Image
    • Orders
      • Validate Order Request
      • Create Order
      • Change Order Status
      • Add Order Comment
      • View Order
      • List Orders
      • List Custom Order Statuses
      • List Order Credit Notes
    • Reverse Orders
      • Create Reverse Orders
      • Create Reverse Orders Waybill
      • Add Reverse Order Reasons
      • List Reverse Reasons
      • Calculate Reverse Totals
      • Create refund for reverse order
      • Upload bank transfer receipt
      • Update return products
      • Order Details – View for Return
    • Abandoned Carts
      • List Carts
      • View Cart
    • Products
      • Managing Products
        • Create Product Types
        • Create Product
          POST
        • List Products
          GET
        • View Product
          GET
        • List Product Settings
          GET
        • Update Product
          PATCH
        • Bulk Update Products
          PATCH
        • Delete Product
          DELETE
      • Digital Vouchers
        • List Vouchers
        • Order Vouchers
        • Create Voucher
        • Import Vouchers
        • Export Vouchers
        • Update Voucher
        • Remove Voucher
      • Product Categories
        • List Categories
        • View Category
        • Create Category
        • Create Subcategory
        • Update Category
        • Assign Product to Category
        • Bulk Assign Products to Category
        • Publish Category
        • Detach Category from All Products
        • Remove Product from Category
      • Product Badge
        • List Badges
      • Product Attributes
        • List Attributes
        • View Attribute
        • Create Attribute
        • Update Attribute
        • Delete Attribute
      • Product Attribute Presets
        • List Presets
        • Create Preset
        • Update Preset
        • Delete Preset
      • Product Variants
        • Create Variants
        • Create Custom Option
        • Update Custom Option
        • Delete Custom Option Field
        • Create Custom Input Field
        • Update Custom Input Field
        • Delete Custom Input Field
      • Product Sorting
        • Set Manual Product Order
        • Reset Manual Product Order
      • Product Images
        • List Images
        • Upload Image
        • Update Image Order
        • Delete Image
      • Product Availability Notifications
        • Notification Stats
        • Noticiation Settings
        • List Notifications
        • Create Notification
        • Update Settings
        • Send Notification Email
        • Export Notifications
      • Product Export
        • Email All Products to Store Owner
        • Import Products via CSV or xlsx File
      • Product Stock
        • Retrieve Product Stock
        • List Product Stock Records
        • Create Product Stock
        • Update Product Stock
        • Bulk Update Product Stock Records
      • Product Questions & Answers
        • Retrieve Product Question
        • Retrieve Product Answer
        • List Product Questions
        • List Answers for Question
        • Create Product Question
        • Create Product Answer
        • Update Product Question
        • Update Product Answer
        • Delete Product Question
        • Delete Product Answer
      • Product Reviews
        • List Reviews
        • Count Reviews
      • Digital Products
        • Create Downloadable Product
        • Generate Upload URL
        • Upload File to S3
        • Create Product Downloadable
        • Get Product Downloadables
        • Delete Product Downloadable
        • List Store Downloadables
        • Create Store Downloadable
        • Delete Store Downloadable
    • Inventories
      • Create Location
      • Update Location
      • Update Product Stock for Location
      • List Locations
      • View Location
    • Shipping
      • List Store Shipping Methods
    • Marketing
      • Coupons
        • List Coupons
        • View Coupon
        • Create Coupon
        • Generate Bulk Coupons
        • Duplicate Coupon
        • Duplicate Bulk Coupons
        • Update Coupon Note
        • Update Coupon
        • Update Bulk Coupons
        • Update Coupon Status
        • Update Bulk Coupons Status
        • Delete Coupon
        • Delete Bulk Coupons
      • Bundle Offers
        • List Bundle Offers
        • View Bundle Offer
      • Loyalty Program
        • Loyalty Program Status
        • Loyalty Program Details
        • Loyalty Program Info
        • Customer Loyalty Summary
        • Customer Points History
        • Activate Loyalty Program
        • Set Points Expiration Rules
        • Update Cashback Rule
        • Create Points Redemption Method
        • Update Points Redemption Method
        • Delete Points Redemption Method
        • Adjust Customer Points
      • Discount Rules
        • List Discount Rules
        • View Discount Rule
        • Create Discount Rule
        • Update Discount Rule
    • Customers
      • Customer Tags
        • List Customer Tags
        • Add Customer Tag
        • ْUpdate Customer Tag
        • Delete Customer Tag
      • List Customers
      • View Customer
      • Primary Customer List
      • FInd Customer By Phone Number
      • Customer Profile
      • Add Customer
      • Update Customer
      • Delete Customer
      • Add Bulk Customers
      • Import Customers
    • Store Settings
      • 📄 User Roles and Permissions
      • Retrieve Store Manager Profile
      • Retrieve VAT Settings
      • List Payment Methods
      • List Store Operating Countries
    • Countries and Cities
      • List Countries
      • List Cities for Country
    • Blogs
      • Settings
        • Create
        • List
      • Categories
        • Create
        • List
        • Bulk Activate
        • Bulk Deactivate
        • Bulk Delete
        • Retrieve
        • Destroy
        • Partial Update
        • Bulk Add To Posts
        • Bulk Remove From Posts
      • Posts
        • Media
          • List
          • Create
          • Destroy
        • Create
        • List
        • Retrieve
        • Partial Update
        • Destroy
        • Archive
        • Publish
        • Bulk Archive
        • Bulk Publish
        • Bulk Delete
        • Export Posts
        • Import Template
        • Import Posts
      • Tags
        • Create
        • List
        • Retrieve
        • Partial Update
        • Destroy
        • Bulk Delete Tags
        • Bulk Add To Posts
        • Bulk Remove From Posts
      • Storefront
        • Posts
          • List
          • Retrieve
        • Categories
          • List
          • Retrieve
        • Tags
          • List
  • Webhooks
    • Overview
    • Webhook Health Tracking
    • Events
      • Order
      • Product
      • Abandoned Cart
      • Customer
      • Product Category
    • APIs
      • Health Summary
      • Broken Webhooks
      • Recover Broken Webhooks
      • List Webhooks
      • Create Webhook
      • Delete Webhook
      • Delete Webhook By subscriber
  • App Management
    • Events
    • APIs
      • Subscription Details
      • Update Usage-Based Charges
  1. Managing Products

Create Product Types

This guide explains how to create different product types using the Create Product endpoint.
All product types are created using the same endpoint:
The request body changes depending on the product type or product_class.
Some product types can be created with a single request. Others, such as Dynamic Bundle products, require an additional API request after the product is created.

💡

Overview#

Use the Create Product endpoint to create:
Standard products
Grouped products
Voucher products
Downloadable products
Crowdfunding projects
Donation items
Customizable products
Dynamic Bundle products
Each product type has different requirements, rules, and supported fields.

Authentication#

The following headers may be required when creating or updating products:
HeaderRequiredDescription
AuthorizationYesBearer JWT for scope-based authentication.
X-Manager-TokenYesEncrypted manager token.
Store-IdYesStore UUID.
RoleYesMust be set to Manager.
Content-TypeYesMust be application/json.
Example:

Product class summary#

Product Typeproduct_class ValueUse CaseAdditional Step Required
Standard ProductNot requiredRegular physical or digital product.No
Grouped Productgrouped_productSell multiple existing products together as one product.No
Voucher ProductvoucherGift cards, license keys, or digital redemption products.May require voucher setup after creation.
Downloadable ProductdownloadableDigital file products such as e-books or documents.Files are managed separately after product creation.
Crowdfunding Projectcrowdfunding_projectFundraising product with goal tracking.No
Donation Itemdonation_itemDonation campaign with unit-based tracking.No
Customizable ProductNot requiredProduct with custom input fields or predefined options.No
Dynamic Bundledynamic_bundleBundle where customers select items from configured groups.Yes. Selection groups must be added separately.

Common product fields#

The following fields are commonly used when creating products.
FieldTypeRequiredDescription
nameobject/stringYesProduct name. Supports an i18n object such as { "ar": "...", "en": "..." } or a plain string.
descriptionobject/stringNoProduct description. Supports an i18n object or a plain string.
short_descriptionobject/stringNoShort product description.
product_classstringConditionalDefines the product type. Not required for standard or customizable products.
skustringNoProduct SKU.
barcodestringNoProduct barcode.
pricenumberYesProduct price. Some product classes have specific price rules.
sale_pricenumberNoDiscounted product price. Not supported by some product classes.
costnumberNoProduct cost.
quantityintegerConditionalProduct quantity. Some product classes calculate or manage quantity automatically.
is_infinitebooleanNoWhether the product has unlimited quantity. Not supported by some product classes.
is_taxablebooleanNoWhether the product is taxable.
requires_shippingbooleanNoWhether the product requires shipping.
weightobjectConditionalProduct weight. Required when shipping is enabled.
is_draftbooleanNoWhether the product is saved as draft.
is_publishedbooleanNoWhether the product is published.
keywordsarrayNoProduct keywords.
seoobjectNoSEO title and description.
badgeobjectNoProduct badge details.
metaobjectConditionalProduct-type-specific metadata.
stocksarrayConditionalProduct stock by inventory location.
group_productsarrayConditionalRequired for grouped products.
custom_user_input_fieldsarrayNoCustomer free-input fields.
custom_option_fieldsarrayNoCustomer predefined option fields.
Note: Categories cannot be added during product creation. To assign a product to one or more categories, use the category assignment endpoints after the product is created.

1. Create a Standard Product#

Use a standard product for regular physical or digital products.
A standard product does not require a product_class value.

Request#

{
  "name": {
    "ar": "منتج عادي",
    "en": "Standard Product"
  },
  "description": {
    "ar": "منتج عادي عام",
    "en": "A regular general product"
  },
  "sku": "STANDARD-001",
  "barcode": "1234567890128",
  "price": 99.99,
  "sale_price": 79.99,
  "quantity": 100,
  "is_taxable": true,
  "requires_shipping": true,
  "weight": {
    "value": 2.5,
    "unit": "kg"
  },
  "is_draft": false,
  "is_published": true,
  "keywords": [
    "product",
    "standard"
  ]
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "منتج عادي",
    "en": "Standard Product"
  },
  "description": {
    "ar": "منتج عادي عام",
    "en": "A regular general product"
  },
  "sku": "STANDARD-001",
  "barcode": "1234567890128",
  "product_class": null,
  "price": 99.99,
  "sale_price": 79.99,
  "quantity": 100,
  "is_infinite": false,
  "is_taxable": true,
  "requires_shipping": true,
  "is_draft": false,
  "is_published": true,
  "weight": {
    "value": 2.5,
    "unit": "kg"
  },
  "meta": {},
  "variants": [],
  "custom_user_input_fields": [],
  "custom_option_fields": [],
  "created_at": "2026-06-10T10:00:00Z",
  "updated_at": "2026-06-10T10:00:00Z"
}

2. Create a Grouped Product#

Use a grouped product to sell multiple existing products together as one product.
Set:
"product_class": "grouped_product"
Grouped products use the group_products array to define which products are included and how many units of each product are part of the group.

Request#

{
  "name": {
    "ar": "منتج مجمع",
    "en": "Grouped Product"
  },
  "description": {
    "ar": "منتج يحتوي على عدة منتجات مرتبطة",
    "en": "A product that includes multiple related products"
  },
  "product_class": "grouped_product",
  "sku": "GROUPED-001",
  "price": 299.99,
  "is_draft": false,
  "is_published": true,
  "requires_shipping": true,
  "stocks": [
    {
      "location": "location-uuid-here",
      "available_quantity": 50,
      "is_infinite": false
    }
  ],
  "group_products": [
    {
      "item_id": "product-uuid-1",
      "item_quantity": 2
    },
    {
      "item_id": "product-uuid-2",
      "item_quantity": 1
    },
    {
      "item_id": "product-uuid-3",
      "item_quantity": 3
    }
  ],
  "weight": {
    "value": 5,
    "unit": "kg"
  }
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "منتج مجمع",
    "en": "Grouped Product"
  },
  "product_class": "grouped_product",
  "sku": "GROUPED-001",
  "price": 299.99,
  "requires_shipping": true,
  "is_draft": false,
  "is_published": true,
  "group_products": [
    {
      "item_id": "product-uuid-1",
      "item_quantity": 2
    },
    {
      "item_id": "product-uuid-2",
      "item_quantity": 1
    },
    {
      "item_id": "product-uuid-3",
      "item_quantity": 3
    }
  ],
  "stocks": [
    {
      "location": "location-uuid-here",
      "available_quantity": 50,
      "is_infinite": false
    }
  ]
}

Grouped product rules#

group_products cannot be empty for published grouped products.
All included products must exist in the store.
All included products must have stock in the same location.
Only published products can be added to a published grouped product.
Weight is calculated automatically from the included products.
Quantity is calculated based on the minimum available units relative to the selected item quantities.

3. Create a Voucher Product#

Use a voucher product for gift cards, license keys, or digital redemption products.
Set:
"product_class": "voucher"
Voucher products are digital products and do not require shipping.

Request#

{
  "name": {
    "ar": "بطاقة هدية",
    "en": "Gift Card"
  },
  "description": {
    "ar": "بطاقة هدية رقمية بقيمة 100 ريال",
    "en": "Digital gift card worth 100 SAR"
  },
  "product_class": "voucher",
  "sku": "VOUCHER-001",
  "price": 100,
  "is_taxable": false,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {}
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "بطاقة هدية",
    "en": "Gift Card"
  },
  "description": {
    "ar": "بطاقة هدية رقمية بقيمة 100 ريال",
    "en": "Digital gift card worth 100 SAR"
  },
  "product_class": "voucher",
  "sku": "VOUCHER-001",
  "price": 100,
  "is_taxable": false,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {}
}

Voucher product rules#

Voucher products automatically set requires_shipping to false.
Voucher products cannot have infinite quantity.
Voucher products cannot have sale_price.
Quantity is handled internally.
The meta field can be used for extension data.

4. Create a Downloadable Product#

Use a downloadable product for digital files such as e-books, documents, or other downloadable assets.
Set:
"product_class": "downloadable"
Downloadable files are managed separately after product creation.

Request#

{
  "name": {
    "ar": "كتاب إلكتروني",
    "en": "E-Book"
  },
  "description": {
    "ar": "كتاب الدليل الشامل",
    "en": "Complete Guide E-Book"
  },
  "product_class": "downloadable",
  "sku": "EBOOK-001",
  "price": 29.99,
  "is_taxable": false,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "download_limit": 5,
    "expiration_period": 30
  }
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "كتاب إلكتروني",
    "en": "E-Book"
  },
  "product_class": "downloadable",
  "sku": "EBOOK-001",
  "price": 29.99,
  "is_taxable": false,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "download_limit": 5,
    "expiration_period": 30
  }
}

Meta properties#

FieldTypeRequiredDescription
download_limitintegerNoMaximum number of downloads allowed.
expiration_periodintegerNoNumber of days before the download link expires.

Downloadable product rules#

Downloadable products automatically set is_infinite to true.
Quantity cannot be overridden.
Downloadable products cannot be shipped.
Files are managed separately after product creation.

5. Create a Crowdfunding Project#

Use a crowdfunding project to collect funds toward a target amount.
Set:
"product_class": "crowdfunding_project"
Crowdfunding products use the meta object to define the funding goal and progress display settings.

Request#

{
  "name": {
    "ar": "تمويل مشروع البئر",
    "en": "Well Drilling Project"
  },
  "description": {
    "ar": "تمويل حفر بئر مياه نظيفة في قرية نائية",
    "en": "Fundraising for drilling a clean water well"
  },
  "product_class": "crowdfunding_project",
  "sku": "CROWDFUND-001",
  "price": 1,
  "is_taxable": true,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "project_goal_amount": 5000,
    "project_external_collected_amount": 1000,
    "show_progress_bar": true,
    "show_progress_percentage": true,
    "show_collected_amount": true,
    "is_open_donation": false
  }
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "تمويل مشروع البئر",
    "en": "Well Drilling Project"
  },
  "product_class": "crowdfunding_project",
  "sku": "CROWDFUND-001",
  "price": 1,
  "is_taxable": true,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "project_goal_amount": 5000,
    "project_external_collected_amount": 1000,
    "show_progress_bar": true,
    "show_progress_percentage": true,
    "show_collected_amount": true,
    "is_open_donation": false
  }
}

Meta properties#

FieldTypeRequiredDescription
project_goal_amountintegerYesTotal amount required to complete the project.
project_external_collected_amountintegerNoAmount already collected outside Zid.
show_progress_barbooleanNoShows or hides the progress bar.
show_progress_percentagebooleanNoShows or hides the progress percentage.
show_collected_amountbooleanNoShows or hides the collected amount.
is_open_donationbooleanNoAllows donations without a fixed goal. When enabled, the goal amount is hidden.

Crowdfunding project rules#

The price is fixed at 1.
Quantity represents the remaining amount needed.
Crowdfunding products cannot have sale_price.
Crowdfunding products cannot have infinite quantity.
Crowdfunding products cannot be shipped.

6. Create a Donation Item#

Use a donation item for donation campaigns with unit-based progress tracking.
Set:
"product_class": "donation_item"
Donation items use the meta object to define total units, externally purchased units, and progress display settings.

Request#

{
  "name": {
    "ar": "وجبة غداء للفقراء",
    "en": "Lunch Meal for the Poor"
  },
  "description": {
    "ar": "وجبة غداء صحية متكاملة",
    "en": "Complete healthy meal"
  },
  "product_class": "donation_item",
  "sku": "DONATION-001",
  "price": 25,
  "is_taxable": true,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "total_units": 200,
    "external_purchased_units": 50,
    "show_progress_bar": true,
    "show_progress_percentage": true,
    "show_purchased_units": true,
    "is_open_donation": false
  }
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "وجبة غداء للفقراء",
    "en": "Lunch Meal for the Poor"
  },
  "product_class": "donation_item",
  "sku": "DONATION-001",
  "price": 25,
  "is_taxable": true,
  "requires_shipping": false,
  "is_draft": false,
  "is_published": true,
  "meta": {
    "total_units": 200,
    "external_purchased_units": 50,
    "show_progress_bar": true,
    "show_progress_percentage": true,
    "show_purchased_units": true,
    "is_open_donation": false
  }
}

Meta properties#

FieldTypeRequiredDescription
total_unitsintegerYesTotal number of donation units available.
external_purchased_unitsintegerNoUnits already purchased outside Zid.
show_progress_barbooleanNoShows or hides the progress bar.
show_progress_percentagebooleanNoShows or hides the progress percentage.
show_purchased_unitsbooleanNoShows or hides the number of purchased units.
is_open_donationbooleanNoAllows donations without a fixed unit goal.

Donation item rules#

Quantity is automatically set based on total_units.
Donation items cannot have sale_price.
Donation items cannot have infinite quantity.
Donation items cannot be shipped.

7. Create a Customizable Product#

Use a customizable product when customers need to provide custom input or select predefined options before adding the product to cart.
Customizable products can include:
custom_user_input_fields
custom_option_fields
Use custom_user_input_fields for free input fields such as text, number, URL, file, image, date, or time.
Use custom_option_fields for predefined options such as dropdowns or checkboxes.
A customizable product does not require a specific product_class value.

Request#

{
  "name": {
    "ar": "كعكة الزفاف المخصصة",
    "en": "Custom Wedding Cake"
  },
  "description": {
    "ar": "كعكة زفاف قابلة للتخصيص مع اسم العروسين",
    "en": "Customizable wedding cake with couple names"
  },
  "sku": "CAKE-001",
  "price": 299.99,
  "is_draft": false,
  "is_published": true,
  "requires_shipping": true,
  "custom_user_input_fields": [
    {
      "type": "TEXT",
      "label": {
        "ar": "اسم العريس",
        "en": "Groom Name"
      },
      "hint": {
        "ar": "أدخل اسم العريس",
        "en": "Enter groom's name"
      },
      "is_required": true,
      "price": 0,
      "display_order": 1,
      "is_published": true
    },
    {
      "type": "TEXT",
      "label": {
        "ar": "اسم العروس",
        "en": "Bride Name"
      },
      "hint": {
        "ar": "أدخل اسم العروس",
        "en": "Enter bride's name"
      },
      "is_required": true,
      "price": 0,
      "display_order": 2,
      "is_published": true
    },
    {
      "type": "NUMBER",
      "label": {
        "ar": "عدد الأشخاص",
        "en": "Number of Guests"
      },
      "hint": {
        "ar": "أدخل عدد الأشخاص",
        "en": "Enter number of guests"
      },
      "is_required": true,
      "price": 50,
      "display_order": 3,
      "is_published": true
    }
  ],
  "custom_option_fields": [
    {
      "type": "select",
      "label": {
        "ar": "نكهة الكعكة",
        "en": "Cake Flavor"
      },
      "hint": {
        "ar": "اختر نكهة الكعكة",
        "en": "Choose cake flavor"
      },
      "is_required": true,
      "can_choose_multiple_options": false,
      "display_order": 1,
      "is_published": true,
      "choices": [
        {
          "id": "flavor-1",
          "ar": "فانيليا كلاسيكية",
          "en": "Classic Vanilla",
          "price": 0
        },
        {
          "id": "flavor-2",
          "ar": "شوكولاتة داكنة",
          "en": "Dark Chocolate",
          "price": 25
        },
        {
          "id": "flavor-3",
          "ar": "فراولة",
          "en": "Strawberry",
          "price": 20
        }
      ]
    },
    {
      "type": "select",
      "label": {
        "ar": "نوع الحشوة",
        "en": "Filling Type"
      },
      "hint": {
        "ar": "اختر نوع الحشوة",
        "en": "Choose filling type"
      },
      "is_required": true,
      "can_choose_multiple_options": false,
      "display_order": 2,
      "is_published": true,
      "choices": [
        {
          "id": "filling-1",
          "ar": "كريمة",
          "en": "Cream",
          "price": 0
        },
        {
          "id": "filling-2",
          "ar": "فاكهة",
          "en": "Fruit",
          "price": 15
        }
      ]
    }
  ]
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "كعكة الزفاف المخصصة",
    "en": "Custom Wedding Cake"
  },
  "sku": "CAKE-001",
  "product_class": null,
  "price": 299.99,
  "is_draft": false,
  "is_published": true,
  "requires_shipping": true,
  "custom_user_input_fields": [
    {
      "id": "custom-field-uuid-1",
      "type": "TEXT",
      "label": {
        "ar": "اسم العريس",
        "en": "Groom Name"
      },
      "hint": {
        "ar": "أدخل اسم العريس",
        "en": "Enter groom's name"
      },
      "is_required": true,
      "price": 0,
      "display_order": 1,
      "is_published": true
    }
  ],
  "custom_option_fields": [
    {
      "id": "option-field-uuid-1",
      "label": {
        "ar": "نكهة الكعكة",
        "en": "Cake Flavor"
      },
      "hint": {
        "ar": "اختر نكهة الكعكة",
        "en": "Choose cake flavor"
      },
      "is_required": true,
      "can_choose_multiple_options": false,
      "display_order": 1,
      "is_published": true,
      "choices": [
        {
          "id": "flavor-1",
          "ar": "فانيليا كلاسيكية",
          "en": "Classic Vanilla",
          "price": 0
        }
      ]
    }
  ]
}

Custom user input field parameters#

FieldTypeRequiredDescription
typestringYesField type. Must be uppercase.
labelobject/stringYesField label. Accepts an i18n object or plain string.
hintobject/stringNoHelper text shown to the customer.
is_requiredbooleanNoWhether the customer must complete the field.
pricenumberNoAdditional price added when the field is used. Defaults to 0.
display_orderintegerNoDisplay order of the field.
is_publishedbooleanNoWhether the field is visible to customers.
Supported custom_user_input_fields[].type values:
Type
TEXT
NUMBER
URL
FILE
IMAGE
DATE
TIME

Custom option field parameters#

FieldTypeRequiredDescription
typestringNoIgnored by the API. The option type is derived from can_choose_multiple_options.
labelobject/stringYesField label. Accepts an i18n object or plain string.
hintobject/stringNoHelper text shown to the customer.
is_requiredbooleanNoWhether the customer must select an option.
can_choose_multiple_optionsbooleanNoDetermines whether the field behaves as a dropdown or checkbox group.
display_orderintegerNoDisplay order of the field.
is_publishedbooleanNoWhether the field is visible to customers.
choicesarrayYesList of predefined choices.

Custom option choice parameters#

FieldTypeRequiredDescription
idstringNoChoice identifier. If omitted, it is generated automatically.
arstringConditionalArabic choice label.
enstringConditionalEnglish choice label.
pricenumberNoAdditional price for the choice. Defaults to 0.

Customizable product rules#

custom_user_input_fields are used for free input fields.
custom_option_fields are used for predefined choices.
custom_user_input_fields[].type must be uppercase.
Lowercase values such as text will be rejected.
custom_option_fields[].type is ignored because the field type is derived from can_choose_multiple_options.
If can_choose_multiple_options is false, the option field behaves like a dropdown.
If can_choose_multiple_options is true, the option field behaves like a checkbox field.
choices[].id is optional. If omitted, it is generated automatically.
choices[].price defaults to 0 if it is not provided.
Each custom option field can have a maximum of 30 choices.
label is required for both field types.
label accepts either an i18n object or a plain string.
Custom fields can be sent inline during product creation or product update.
When updating existing fields, include id to update the field.
To remove an existing field, send is_deleted: true.

8. Create a Dynamic Bundle Product#

Use a Dynamic Bundle product when customers need to select items from one or more selection groups.
Set:
"product_class": "dynamic_bundle"
Dynamic Bundle products require two API requests:
1.
Create the Dynamic Bundle product using POST /v1/products/
2.
Add selection groups using PATCH /v1/products/{product_id}/selection-groups/bulk-patch/
If the product is created as a draft, use this flow:
1.
Create the product as draft using POST /v1/products/
2.
Add selection groups using PATCH /v1/products/{product_id}/selection-groups/bulk-patch/
3.
Publish the product using PATCH /v1/products/{id}/

Step 1: Create the Dynamic Bundle product#

{
  "name": {
    "ar": "حزمة البناء المخصصة",
    "en": "Custom Build Bundle"
  },
  "description": {
    "ar": "اختر المكونات الخاصة بك لإنشاء حزمة فريدة",
    "en": "Choose your components to create a unique bundle"
  },
  "product_class": "dynamic_bundle",
  "sku": "BUNDLE-001",
  "price": 0,
  "is_draft": false,
  "is_published": false,
  "requires_shipping": true,
  "meta": {
    "location_id": "dd125776-70d1-4819-934c-a29b8ebd18ca"
  }
}

Successful response example#

{
  "id": "product-uuid",
  "name": {
    "ar": "حزمة البناء المخصصة",
    "en": "Custom Build Bundle"
  },
  "description": {
    "ar": "اختر المكونات الخاصة بك لإنشاء حزمة فريدة",
    "en": "Choose your components to create a unique bundle"
  },
  "product_class": "dynamic_bundle",
  "sku": "BUNDLE-001",
  "price": 0,
  "is_draft": false,
  "is_published": false,
  "requires_shipping": true,
  "meta": {
    "location_id": "dd125776-70d1-4819-934c-a29b8ebd18ca"
  },
  "selection_groups": []
}

Dynamic Bundle product rules#

price: 0 is commonly used because the final price is calculated from the selected bundle items.
meta.location_id should match the inventory location where all bundle items have stock.
Dynamic Bundle products require selection groups before they can be published.
Use is_draft: true if you want to create the product first and add selection groups later.
All bundle items must have stock in the same location_id.

Step 2: Add selection groups#

Use the bulk patch selection groups endpoint to add, update, or delete selection groups for the Dynamic Bundle product.

Request body#

{
  "location_id": "dd125776-70d1-4819-934c-a29b8ebd18ca",
  "selection_groups": [
    {
      "name": {
        "ar": "اختر اللون",
        "en": "Choose Color"
      },
      "required_selection_count": 1,
      "allow_duplicate_items": false,
      "items": [
        {
          "item_id": "standalone-product-uuid"
        },
        {
          "item_id": "parent-product-uuid",
          "variant_ids": [
            "variant-child-uuid-1",
            "variant-child-uuid-2"
          ]
        }
      ]
    }
  ]
}

Successful response example#

{
  "id": "product-uuid",
  "product_class": "dynamic_bundle",
  "selection_groups": [
    {
      "selection_group_id": "selection-group-uuid",
      "name": {
        "ar": "اختر اللون",
        "en": "Choose Color"
      },
      "required_selection_count": 1,
      "allow_duplicate_items": false,
      "items": [
        {
          "item_id": "standalone-product-uuid",
          "variant_ids": null
        },
        {
          "item_id": "parent-product-uuid",
          "variant_ids": [
            "variant-child-uuid-1",
            "variant-child-uuid-2"
          ]
        }
      ]
    }
  ]
}

Selection group body parameters#

FieldTypeRequiredDescription
location_idstringYesInventory location UUID. All bundle items must have stock in this location.
selection_groupsarrayYesList of selection groups to add, update, or delete.
selection_groups[].selection_group_idstringNoExisting selection group UUID. Include only when updating or deleting an existing group.
selection_groups[].nameobject/stringYesSelection group name. Accepts an i18n object or a plain string.
selection_groups[].required_selection_countintegerYesNumber of items the customer must select from this group. Must be less than or equal to the number of items in the group.
selection_groups[].allow_duplicate_itemsbooleanNoDetermines whether duplicate items are allowed. Defaults to false.
selection_groups[].itemsarrayYesList of products available for selection in the group.
selection_groups[].items[].item_idstringYesProduct UUID of the item added to the selection group.
selection_groups[].items[].variant_idsarray/nullConditionalRequired when item_id belongs to a parent product with options or variants. Omit or set to null for standalone products.
selection_groups[].is_deletedbooleanNoSet to true to delete an existing selection group. Use only with selection_group_id.

Dynamic Bundle item rules#

Standalone products#

If the item is a standalone product with no variants, send only item_id.
{
  "item_id": "1be029e1-b627-48db-88ab-1c6595428915"
}
You can omit variant_ids entirely or set it to null.

Parent products with variants#

If the item is a parent product that has options or variants, variant_ids is required.
{
  "item_id": "parent-product-uuid",
  "variant_ids": [
    "variant-uuid-1",
    "variant-uuid-2"
  ]
}
If a parent product is sent without variant_ids, the API returns an error because at least one child variant must be selected.

Full Dynamic Bundle selection group example#

{
  "location_id": "dd125776-70d1-4819-934c-a29b8ebd18ca",
  "selection_groups": [
    {
      "name": {
        "ar": "اختر اللون",
        "en": "Choose Color"
      },
      "required_selection_count": 1,
      "allow_duplicate_items": false,
      "items": [
        {
          "item_id": "standalone-product-uuid"
        },
        {
          "item_id": "parent-product-uuid",
          "variant_ids": [
            "variant-child-uuid-1",
            "variant-child-uuid-2"
          ]
        }
      ]
    },
    {
      "name": {
        "ar": "اختر المقاس",
        "en": "Choose Size"
      },
      "required_selection_count": 1,
      "allow_duplicate_items": false,
      "items": [
        {
          "item_id": "another-product-uuid"
        }
      ]
    }
  ]
}

Step 3: Publish the Dynamic Bundle product#

If the Dynamic Bundle product was created as a draft, publish it after adding selection groups.
Example request:
{
  "is_draft": false,
  "is_published": true
}
The product must contain at least one valid selection group before it can be published.

Complete product example#

The following example shows a product with multiple supported fields.
{
  "name": {
    "ar": "منتج شامل",
    "en": "Comprehensive Product"
  },
  "description": {
    "ar": "منتج يوضح جميع الميزات المتاحة",
    "en": "Product showcasing all available features"
  },
  "short_description": {
    "ar": "منتج شامل مع جميع الميزات",
    "en": "Comprehensive product with all features"
  },
  "sku": "FULL-001",
  "barcode": "1234567890128",
  "price": 199.99,
  "sale_price": 149.99,
  "cost": 80,
  "quantity": 100,
  "is_infinite": false,
  "is_draft": false,
  "is_published": true,
  "is_taxable": true,
  "requires_shipping": true,
  "weight": {
    "value": 1.5,
    "unit": "kg"
  },
  "keywords": [
    "product",
    "complete",
    "featured"
  ],
  "display_order": 1,
  "seo": {
    "title": {
      "ar": "منتج شامل - متجر متقدم",
      "en": "Comprehensive Product - Advanced Store"
    },
    "description": {
      "ar": "اكتشف منتجنا الشامل بميزات متقدمة",
      "en": "Discover our comprehensive product with advanced features"
    }
  },
  "purchase_restrictions": {
    "min_quantity_per_cart": 1,
    "max_quantity_per_cart": 5,
    "availability_period_start": "2024-01-01T00:00:00Z",
    "availability_period_end": "2024-12-31T23:59:59Z",
    "sale_price_period_start": "2024-01-01T00:00:00Z",
    "sale_price_period_end": "2024-03-31T23:59:59Z"
  },
  "badge": {
    "body": {
      "ar": "خصم {discount_percent}",
      "en": "Discount {discount_percent}"
    }
  }
}

Common error responses#

The API may return validation errors when required fields are missing or unsupported fields are sent for a product class.

Invalid request example#

{
  "message": "The given data was invalid.",
  "errors": {
    "price": [
      "The price field is required."
    ]
  }
}

Unauthorized request example#

{
  "message": "Unauthenticated."
}

Forbidden request example#

{
  "message": "This action is unauthorized."
}

Dynamic Bundle common errors#

ErrorCauseHow to Fix
Bundle Product must contain at least 1 selection groupThe Dynamic Bundle product was published or updated before adding selection groups.Add selection groups using the bulk patch endpoint before publishing the product.
No location found with the given ID=Nonelocation_id is missing from the request body.Add location_id at the top level of the request body.
For products with options, at least one variant must be selectedThe selected item_id belongs to a parent product with variants.Add variant_ids with at least one child variant UUID.
A selection group must have at least 1 itemThe items array is empty.Add at least one item to the selection group.
required_selection_count must be less than or equal to items countThe required selection count is greater than the number of available items.Reduce required_selection_count or add more items to the group.
Location ID must be specified for dynamic bundle productmeta.location_id is missing from the product or location_id is missing from the bulk patch request.Add the location ID in both the product metadata and the selection group request.
All items in a dynamic bundle must have quantity in the same locationOne or more items do not have stock in the selected location.Make sure every item has stock in the specified location_id.
You can't add more than 10 selection groupsThe request includes more than 10 selection groups.Keep the number of selection groups to 10 or fewer.
Product [uuid] has no stockThe selected item does not have stock in the bundle location.Add stock for the product in the selected location.

Dynamic Bundle validation error example#

{
  "message": "For products with options, at least one variant must be selected",
  "errors": {
    "selection_groups.0.items.1.variant_ids": [
      "For products with options, at least one variant must be selected"
    ]
  }
}

Related endpoints#

MethodEndpointPurpose
POST/v1/products/Create a product.
PATCH/v1/products/{id}/Update product fields or publish a product.
PATCH/v1/products/{product_id}/selection-groups/bulk-patch/Add, update, or delete Dynamic Bundle selection groups.
GET/v1/products/{id}/Retrieve product details.
GET/v1/products/List products.

Best practices#

Use the correct product_class value for the product type.
Do not send product_class for standard products unless required by your implementation.
Do not add categories during product creation. Assign categories after the product is created.
For Dynamic Bundle products, always add selection groups before publishing.
For Dynamic Bundle items with variants, include at least one valid child variant UUID in variant_ids.
Make sure all Dynamic Bundle items have stock in the same location_id.
Keep Dynamic Bundle selection groups to 10 or fewer.
Use is_draft: true when you need to create a product first and complete its configuration later.
Use actual product UUIDs, variant UUIDs, and location UUIDs from the store when testing requests.
Use the API response from your testing environment as the final source of truth for exact field names and response structure.
Modified at 2026-06-10 07:48:59
Previous
Managing Products
Next
Create Product
Built with