Product Variants Guide
Overview
Product variants allow you to manage products with multiple variations (size, color, style, etc.) efficiently. Instead of creating dozens of individual products, you define a master product with variant attributes, then generate all combinations automatically. Each variant gets its own SKU, pricing, and inventory tracking while inheriting base properties from the master.
Table of Contents
- Concepts
- Master Product Configuration
- Generating Variants
- Creating Individual Variants
- Variant Naming and SKU Generation
- Managing Variant Inventory
- Managing Variant Pricing
- Deleting Variants
- Available Variant Values
- Use Cases and Examples
- API Endpoints
Concepts
Master Product
A template product that defines:
- Base properties (name, description, category, supplier)
- Variant attributes (which properties vary)
- Attribute values (options for each attribute)
Key Characteristics:
- No direct SKU
- No inventory tracking
- Configuration only
- Not directly sellable
Example:
[
'name' => 'T-Shirt - Cotton Basic',
'type' => 'physical',
'is_variant' => false,
'variant_configuration' => [
'attributes' => [
'Size' => ['S', 'M', 'L', 'XL'],
'Color' => ['Red', 'Blue', 'Black', 'White'],
],
],
]Variant Product
An individual product created from master configuration:
Key Characteristics:
- Unique SKU
- Individual inventory tracking
- Can override master pricing
- Specific attribute combination
- Directly sellable
Example:
[
'name' => 'T-Shirt - Cotton Basic (M, Blue)',
'sku' => 'TSHIRT-BASIC-M-BLUE',
'type' => 'physical',
'is_variant' => true,
'parent_product_id' => 1,
'variant_attributes' => [
'Size' => 'M',
'Color' => 'Blue',
],
'selling_price' => Money::fromFloat(19.99),
'stock_quantity' => 25,
]Variant Attributes
Dimensions of variation for a product:
Common Examples:
- Size: S, M, L, XL, XXL
- Color: Red, Blue, Black, White
- Material: Cotton, Polyester, Blend
- Style: Regular, Slim, Relaxed
- Capacity: 8GB, 16GB, 32GB, 64GB
- Flavor: Vanilla, Chocolate, Strawberry
- Version: Basic, Pro, Enterprise
Cartesian Product
All possible combinations of attribute values:
Size: [S, M, L] (3 values)
Color: [Red, Blue] (2 values)
Cartesian Product: 3 × 2 = 6 combinations
- (S, Red)
- (S, Blue)
- (M, Red)
- (M, Blue)
- (L, Red)
- (L, Blue)Master Product Configuration
Creating a Master Product
Define variant attributes during product creation:
curl -X POST https://api.crm.test/api/v1/operations/products \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "T-Shirt - Cotton Basic",
"type": "physical",
"category_id": 5,
"supplier_id": 2,
"description": "Premium cotton t-shirt",
"variant_configuration": {
"attributes": {
"Size": ["S", "M", "L", "XL"],
"Color": ["Red", "Blue", "Black", "White"]
}
}
}'Result: Master product configured for 16 variants (4 sizes × 4 colors)
Variant Configuration Structure
'variant_configuration' => [
'attributes' => [
'Attribute1Name' => ['Value1', 'Value2', 'Value3'],
'Attribute2Name' => ['ValueA', 'ValueB'],
'Attribute3Name' => ['Option1', 'Option2', 'Option3'],
],
]Rules:
- Minimum 2 attributes required
- Each attribute must have at least 1 value
- Maximum 1000 total combinations (safety limit)
- Attribute names should be descriptive (e.g., "Size" not "S")
- Values should be user-friendly (e.g., "Extra Large" or "XL")
Complex Example
Laptop with multiple variant dimensions:
{
"name": "Laptop - Professional Series",
"variant_configuration": {
"attributes": {
"RAM": ["8GB", "16GB", "32GB"],
"Storage": ["256GB SSD", "512GB SSD", "1TB SSD"],
"Processor": ["Intel i5", "Intel i7", "Intel i9"],
"Color": ["Silver", "Space Gray"]
}
}
}Total Combinations: 3 × 3 × 3 × 2 = 54 variants
Generating Variants
Automatic Generation (All Combinations)
Generate all possible variants from master configuration:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants/generate \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"auto_generate_sku": true,
"sku_prefix": "TSHIRT-",
"initial_stock": 0
}'Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
auto_generate_sku | boolean | No | Auto-generate SKUs (default: true) |
sku_prefix | string | No | SKU prefix (e.g., "TSHIRT-") |
initial_stock | integer | No | Initial stock for each variant (default: 0) |
Response:
{
"message": "Generated 16 variant(s) successfully",
"data": {
"generated_count": 16,
"variants": [
{
"id": 42,
"name": "T-Shirt - Cotton Basic (S, Red)",
"sku": "TSHIRT-BASIC-S-RED",
"variant_attributes": {"Size": "S", "Color": "Red"},
"stock_quantity": 0
},
{
"id": 43,
"name": "T-Shirt - Cotton Basic (S, Blue)",
"sku": "TSHIRT-BASIC-S-BLUE",
"variant_attributes": {"Size": "S", "Color": "Blue"},
"stock_quantity": 0
}
// ... 14 more variants
]
}
}Generation Process
The system follows this workflow:
graph TD
A[Master Product] --> B[Retrieve Variant Configuration]
B --> C[Calculate Cartesian Product]
C --> D{Validate Count}
D -->|> 1000| E[Error: Too Many Variants]
D -->|≤ 1000| F[Generate SKUs]
F --> G[Create Variant Records]
G --> H[Initialize Inventory]
H --> I[Return Created Variants]Steps:
- Retrieve Configuration: Get variant attributes from master product
- Calculate Combinations: Compute cartesian product
- Validate Count: Ensure <= 1000 combinations (safety)
- Skip Existing: Don't recreate existing combinations (idempotent)
- Generate SKUs: Create unique SKUs per variant
- Inherit Properties: Copy name, description, category, supplier from master
- Append Attributes: Add variant attributes to product name
- Create Records: Insert variant products in database
- Initialize Inventory: Set initial stock levels
- Return Results: List all created variants
SKU Generation Logic
Format: {sku_prefix}{master_base_sku}-{attr1_value}-{attr2_value}
Example:
Master SKU: "TSHIRT-BASIC"
Prefix: "TSHIRT-"
Variant: Size=M, Color=Blue
Generated SKU: "TSHIRT-BASIC-M-BLUE"Slugification:
- Converts values to URL-safe format
- Removes special characters
- Uppercase letters converted to uppercase
- Spaces become hyphens
Examples:
- "Extra Large" → "EXTRA-LARGE"
- "256GB SSD" → "256GB-SSD"
- "Space Gray" → "SPACE-GRAY"
Uniqueness:
- Checks for conflicts with existing SKUs
- Falls back to sequential numbers if needed:
TSHIRT-BASIC-001,TSHIRT-BASIC-002
Variant Property Inheritance
Variants inherit these properties from master:
| Property | Inherited | Can Override |
|---|---|---|
| Name (base) | ✅ Yes | ❌ No (appended) |
| Description | ✅ Yes | ✅ Yes |
| Category | ✅ Yes | ❌ No |
| Supplier | ✅ Yes | ❌ No |
| Brand | ✅ Yes | ❌ No |
| Tax Class | ✅ Yes | ✅ Yes |
| Selling Price | ✅ Yes | ✅ Yes |
| Cost Price | ✅ Yes | ✅ Yes |
| Type | ✅ Yes | ❌ No |
| SKU | ❌ No (generated) | ✅ Yes |
| Stock | ❌ No (individual) | ✅ Yes |
| Status | ❌ No (starts draft) | ✅ Yes |
| Images | ❌ No (individual) | ✅ Yes |
Creating Individual Variants
For selective variant creation, create specific combinations manually:
Use Cases
- Limited Edition: Only certain color/size combos
- Testing: Create popular variants first
- Phased Rollout: Gradual variant introduction
- Regional Variations: Specific markets get specific options
- Correcting Gaps: Fill in missing combinations later
API Request
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"variant_attributes": {
"Size": "M",
"Color": "Blue"
},
"sku": "TSHIRT-BASIC-M-BLUE",
"selling_price": 19.99,
"stock_quantity": 50
}'Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
variant_attributes | object | ✅ Yes | Attribute key-value pairs |
sku | string | No | Custom SKU (auto-generated if not provided) |
selling_price | float | No | Override master price |
cost_price | float | No | Override master cost |
stock_quantity | integer | No | Initial stock (default: 0) |
Response:
{
"message": "Variant created successfully",
"data": {
"id": 42,
"name": "T-Shirt - Cotton Basic (M, Blue)",
"sku": "TSHIRT-BASIC-M-BLUE",
"type": "physical",
"is_variant": true,
"parent_product_id": 1,
"variant_attributes": {
"Size": "M",
"Color": "Blue"
},
"selling_price": 19.99,
"stock_quantity": 50
}
}Validation
The system validates:
- ✅ Attribute keys match master configuration
- ✅ Attribute values exist in master configuration
- ✅ Combination doesn't already exist
- ✅ SKU is unique across all products
- ✅ All required variant attributes provided
Error Example:
{
"message": "Validation failed",
"errors": {
"variant_attributes.Color": [
"Color value 'Purple' not found in master configuration. Available: Red, Blue, Black, White"
]
}
}Variant Naming and SKU Generation
Automatic Naming
Variants are named by appending attributes to master name:
Pattern: {master_name} ({attr1_value}, {attr2_value}, ...)
Examples:
| Master Name | Attributes | Variant Name |
|---|---|---|
| "T-Shirt - Cotton Basic" | Size: M, Color: Blue | "T-Shirt - Cotton Basic (M, Blue)" |
| "Laptop - Pro Series" | RAM: 16GB, Storage: 512GB SSD | "Laptop - Pro Series (16GB, 512GB SSD)" |
| "Coffee - Premium Blend" | Size: Medium, Roast: Dark | "Coffee - Premium Blend (Medium, Dark)" |
Custom Naming
Override automatic naming with custom variant names:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants \
-H "Authorization: Bearer {token}" \
-d '{
"variant_attributes": {"Size": "L", "Color": "Red"},
"name": "T-Shirt - Limited Edition Red (Large)"
}'SKU Best Practices
Recommended Format: {CATEGORY}-{PRODUCT}-{VARIANT_IDENTIFIERS}
Examples:
APPAREL-TSHIRT-BASIC-M-BLUE
LAPTOP-PRO-16GB-512GB-SILVER
COFFEE-PREMIUM-MEDIUM-DARKBenefits:
- Readable: Easy to understand what product it is
- Sortable: Groups related variants together
- Unique: Prevents duplicates
- Scannable: Works with barcode systems
Avoid:
- Sequential numbers only (PROD-001, PROD-002) - no context
- Random strings (AHDK23D) - not human-readable
- Too long (> 50 characters) - barcode issues
Managing Variant Inventory
Individual Variant Stock
Each variant has separate inventory tracking:
# Update specific variant stock
curl -X PUT https://api.crm.test/api/v1/operations/products/42 \
-H "Authorization: Bearer {token}" \
-d '{
"stock_quantity": 100,
"reorder_point": 20
}'Bulk Stock Update (All Variants)
Set same stock level for all variants of a master:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants/bulk-update-stock \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"quantity": 50
}'Use Cases:
- Initial stock setup after generation
- Uniform replenishment across all variants
- Resetting stock for inventory count
- Setting all to zero for transfers
Response:
{
"message": "Updated stock to 50 for 16 variant(s)",
"meta": {
"updated_count": 16,
"quantity": 50
}
}Stock by Variant
View inventory levels for all variants:
curl -X GET https://api.crm.test/api/v1/operations/master-products/1/variants \
-H "Authorization: Bearer {token}"Response:
{
"data": [
{
"id": 42,
"sku": "TSHIRT-BASIC-S-RED",
"variant_attributes": {"Size": "S", "Color": "Red"},
"stock_quantity": 45,
"available_quantity": 42,
"reserved_quantity": 3
},
{
"id": 43,
"sku": "TSHIRT-BASIC-S-BLUE",
"variant_attributes": {"Size": "S", "Color": "Blue"},
"stock_quantity": 38,
"available_quantity": 38,
"reserved_quantity": 0
}
// ... more variants
],
"meta": {
"total_variants": 16,
"total_stock": 680,
"total_available": 652,
"total_reserved": 28
}
}Managing Variant Pricing
Individual Variant Pricing
Set unique pricing per variant:
# Premium pricing for XL sizes
curl -X PUT https://api.crm.test/api/v1/operations/products/45 \
-H "Authorization: Bearer {token}" \
-d '{
"selling_price": 24.99
}'Use Cases:
- Size premiums (XL, XXL cost more)
- Color surcharges (special finishes)
- Capacity pricing (more storage = higher price)
- Material costs (premium fabrics)
Bulk Price Update (All Variants)
Set uniform pricing across all variants:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants/bulk-update-prices \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"price": 19.99
}'Use Cases:
- Promotional pricing (flash sale)
- Seasonal discounts
- Market adjustments
- Simplifying pricing strategy
Response:
{
"message": "Updated price to 19.99 for 16 variant(s)",
"meta": {
"updated_count": 16,
"price": 19.99
}
}Price Inheritance
Clear variant price overrides to inherit from master:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants/bulk-update-prices \
-H "Authorization: Bearer {token}" \
-d '{
"price": null
}'Effect:
- Variants no longer have explicit prices
- Inherit master product price automatically
- Master price changes apply to all variants
- Centralized price management
Response:
{
"message": "Cleared price overrides for 16 variant(s)",
"meta": {
"updated_count": 16,
"price": null,
"operation": "clear_overrides",
"variants_now_inherit": true,
"master_price": 24.99
}
}Pricing Strategies
Strategy 1: Uniform Pricing All variants same price:
S, M, L, XL = $19.99Strategy 2: Size-Based Pricing Larger sizes cost more:
S, M = $19.99
L = $22.99
XL = $24.99Strategy 3: Master Inheritance All inherit from master, centralized control:
Master Price: $19.99
All Variants: $19.99 (inherited)
Update master → all variants followStrategy 4: Attribute-Based Pricing Different prices per attribute combination:
Standard Colors (Red, Blue, Black): $19.99
Premium Color (White): $22.99Deleting Variants
Delete All Variants
Remove all variants for a master product:
curl -X POST https://api.crm.test/api/v1/operations/master-products/1/variants/delete-all \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"confirmation": true
}'Use Cases:
- Regenerating variants with new configuration
- Correcting bulk generation errors
- Seasonal catalog reset
- Configuration changes requiring fresh start
Response:
{
"message": "Deleted 16 variant(s) successfully",
"meta": {
"deleted_count": 16,
"master_id": 1,
"master_name": "T-Shirt - Cotton Basic",
"deletion_type": "soft_delete",
"can_be_restored": true
}
}Important Notes:
- Soft Delete: Variants are soft-deleted (can be restored by DB admin)
- Inventory Preserved: Stock history maintained for audit
- Order History: References to variants in orders remain intact
- Destructive: Cannot be easily undone via UI
Pre-Deletion Checklist:
- [ ] Verify no active orders for these variants
- [ ] Check no pending purchase orders
- [ ] Ensure backup if data needed
- [ ] Notify stakeholders (sales, warehouse)
Delete Individual Variant
Remove specific variant:
curl -X DELETE https://api.crm.test/api/v1/operations/products/42 \
-H "Authorization: Bearer {token}"Use Cases:
- Removing discontinued color/size
- Correcting mistakenly created variant
- Eliminating poor-selling combinations
Available Variant Values
Check which combinations haven't been created yet:
curl -X GET https://api.crm.test/api/v1/operations/master-products/1/variants/available \
-H "Authorization: Bearer {token}"Response:
{
"data": {
"available_combinations": [
{"Size": "S", "Color": "Black"},
{"Size": "M", "Color": "Black"},
{"Size": "L", "Color": "Black"},
{"Size": "XL", "Color": "Black"}
],
"available_by_attribute": {
"Size": {
"S": {"available": true, "combinations_count": 1},
"M": {"available": true, "combinations_count": 1},
"L": {"available": true, "combinations_count": 1},
"XL": {"available": true, "combinations_count": 1}
},
"Color": {
"Red": {"available": false, "combinations_count": 0},
"Blue": {"available": false, "combinations_count": 0},
"Black": {"available": true, "combinations_count": 4},
"White": {"available": false, "combinations_count": 0}
}
},
"statistics": {
"total_possible_combinations": 16,
"existing_variants": 12,
"available_combinations": 4,
"completion_percent": 75.0
}
}
}Use Cases:
- UI dropdowns for "Create Variant" forms
- Progress tracking ("12 of 16 variants created")
- Identifying gaps in variant matrix
- Validation before manual variant creation
- Suggesting next variants to create
Use Cases and Examples
Example 1: Apparel Store
Scenario: T-shirt with multiple sizes and colors
{
"name": "T-Shirt - Cotton Basic",
"variant_configuration": {
"attributes": {
"Size": ["XS", "S", "M", "L", "XL", "XXL"],
"Color": ["Red", "Blue", "Black", "White", "Gray"]
}
}
}Result: 6 × 5 = 30 variants
Pricing Strategy: Size-based
- XS, S, M, L: $19.99
- XL: $21.99
- XXL: $23.99
Example 2: Electronics Store
Scenario: Smartphone with capacity and color options
{
"name": "Smartphone - Pro Series",
"variant_configuration": {
"attributes": {
"Storage": ["64GB", "128GB", "256GB", "512GB"],
"Color": ["Space Gray", "Silver", "Gold", "Blue"]
}
}
}Result: 4 × 4 = 16 variants
Pricing Strategy: Storage-based
- 64GB: $699
- 128GB: $799
- 256GB: $899
- 512GB: $1099
Example 3: Coffee Subscription
Scenario: Coffee subscriptions with roast and size
{
"name": "Coffee Subscription - Premium Blend",
"type": "subscription",
"variant_configuration": {
"attributes": {
"Roast": ["Light", "Medium", "Dark", "French"],
"Bag Size": ["8oz", "16oz", "32oz"]
}
}
}Result: 4 × 3 = 12 variants
Pricing Strategy: Bag size-based
- 8oz: $14.99/month
- 16oz: $24.99/month
- 32oz: $44.99/month
Example 4: Furniture Store
Scenario: Sofa with fabric and color options
{
"name": "Sofa - Modern 3-Seater",
"variant_configuration": {
"attributes": {
"Fabric": ["Leather", "Linen", "Velvet", "Microfiber"],
"Color": ["Beige", "Gray", "Navy", "Charcoal"]
}
}
}Result: 4 × 4 = 16 variants
Pricing Strategy: Fabric-based
- Microfiber: $899
- Linen: $1199
- Velvet: $1399
- Leather: $1899
Example 5: SaaS Subscriptions
Scenario: Software with plan tiers and billing cycles
{
"name": "Cloud Storage Service",
"type": "subscription",
"variant_configuration": {
"attributes": {
"Plan": ["Basic", "Pro", "Business", "Enterprise"],
"Billing": ["Monthly", "Annual"]
}
}
}Result: 4 × 2 = 8 variants
Pricing Strategy: Plan + billing discount
- Basic Monthly: $9.99, Annual: $99 (save 17%)
- Pro Monthly: $19.99, Annual: $199 (save 17%)
- Business Monthly: $49.99, Annual: $499 (save 17%)
- Enterprise: Custom pricing
API Endpoints
Master Product Operations
| Method | Endpoint | Description |
|---|---|---|
| POST | /products | Create master product with variant config |
| GET | /products/{id} | Get master product details |
| PUT | /products/{id} | Update master configuration |
Variant Generation
| Method | Endpoint | Description |
|---|---|---|
| POST | /master-products/{master}/variants/generate | Generate all variants automatically |
| POST | /master-products/{master}/variants | Create individual variant |
| GET | /master-products/{master}/variants | List all variants for master |
| GET | /master-products/{master}/variants/available | Get available attribute combinations |
Variant Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /products/{variant_id} | Get variant details |
| PUT | /products/{variant_id} | Update variant properties |
| DELETE | /products/{variant_id} | Delete variant |
Bulk Variant Operations
| Method | Endpoint | Description |
|---|---|---|
| POST | /master-products/{master}/variants/bulk-update-stock | Update stock for all variants |
| POST | /master-products/{master}/variants/bulk-update-prices | Update prices for all variants |
| POST | /master-products/{master}/variants/delete-all | Delete all variants |
See: API Reference for complete documentation.
Related Guides
- Product Management - Core product concepts
- Multi-Warehouse Inventory - Variant inventory tracking
- Purchase Orders - Ordering variant products
- Value Objects - Money, SKU value objects
Next Steps
- Create Master Product - Follow Product Management Guide
- Generate Variants - Use the automatic generation endpoint
- Manage Inventory - Read Multi-Warehouse Inventory Guide
- Complete Tutorial - Follow Product Variants Tutorial