Skip to content

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

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:

php
[
    '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:

php
[
    '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:

bash
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

php
'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:

json
{
  "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:

bash
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:

ParameterTypeRequiredDescription
auto_generate_skubooleanNoAuto-generate SKUs (default: true)
sku_prefixstringNoSKU prefix (e.g., "TSHIRT-")
initial_stockintegerNoInitial stock for each variant (default: 0)

Response:

json
{
  "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:

mermaid
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:

  1. Retrieve Configuration: Get variant attributes from master product
  2. Calculate Combinations: Compute cartesian product
  3. Validate Count: Ensure <= 1000 combinations (safety)
  4. Skip Existing: Don't recreate existing combinations (idempotent)
  5. Generate SKUs: Create unique SKUs per variant
  6. Inherit Properties: Copy name, description, category, supplier from master
  7. Append Attributes: Add variant attributes to product name
  8. Create Records: Insert variant products in database
  9. Initialize Inventory: Set initial stock levels
  10. 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:

PropertyInheritedCan 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

bash
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:

ParameterTypeRequiredDescription
variant_attributesobject✅ YesAttribute key-value pairs
skustringNoCustom SKU (auto-generated if not provided)
selling_pricefloatNoOverride master price
cost_pricefloatNoOverride master cost
stock_quantityintegerNoInitial stock (default: 0)

Response:

json
{
  "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:

json
{
  "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 NameAttributesVariant 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:

bash
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-DARK

Benefits:

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

bash
# 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:

bash
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:

json
{
  "message": "Updated stock to 50 for 16 variant(s)",
  "meta": {
    "updated_count": 16,
    "quantity": 50
  }
}

Stock by Variant

View inventory levels for all variants:

bash
curl -X GET https://api.crm.test/api/v1/operations/master-products/1/variants \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "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:

bash
# 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:

bash
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:

json
{
  "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:

bash
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:

json
{
  "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.99

Strategy 2: Size-Based Pricing Larger sizes cost more:

S, M = $19.99
L = $22.99
XL = $24.99

Strategy 3: Master Inheritance All inherit from master, centralized control:

Master Price: $19.99
All Variants: $19.99 (inherited)
Update master → all variants follow

Strategy 4: Attribute-Based Pricing Different prices per attribute combination:

Standard Colors (Red, Blue, Black): $19.99
Premium Color (White): $22.99

Deleting Variants

Delete All Variants

Remove all variants for a master product:

bash
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:

json
{
  "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:

bash
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:

bash
curl -X GET https://api.crm.test/api/v1/operations/master-products/1/variants/available \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "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

json
{
  "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

json
{
  "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

json
{
  "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

json
{
  "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

json
{
  "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

MethodEndpointDescription
POST/productsCreate master product with variant config
GET/products/{id}Get master product details
PUT/products/{id}Update master configuration

Variant Generation

MethodEndpointDescription
POST/master-products/{master}/variants/generateGenerate all variants automatically
POST/master-products/{master}/variantsCreate individual variant
GET/master-products/{master}/variantsList all variants for master
GET/master-products/{master}/variants/availableGet available attribute combinations

Variant Management

MethodEndpointDescription
GET/products/{variant_id}Get variant details
PUT/products/{variant_id}Update variant properties
DELETE/products/{variant_id}Delete variant

Bulk Variant Operations

MethodEndpointDescription
POST/master-products/{master}/variants/bulk-update-stockUpdate stock for all variants
POST/master-products/{master}/variants/bulk-update-pricesUpdate prices for all variants
POST/master-products/{master}/variants/delete-allDelete all variants

See: API Reference for complete documentation.

Next Steps

  1. Create Master Product - Follow Product Management Guide
  2. Generate Variants - Use the automatic generation endpoint
  3. Manage Inventory - Read Multi-Warehouse Inventory Guide
  4. Complete Tutorial - Follow Product Variants Tutorial

Documentation for SynthesQ CRM/ERP Platform