Product Attributes Guide
Overview
The Product Attributes system allows you to define and manage dynamic, flexible attributes for products through the REST API. This guide covers attribute types, validation rules, API endpoints, and best practices for using attributes to create rich product catalogs.
Understanding Product Attributes
What are Product Attributes?
Product attributes are customizable properties that provide detailed product information beyond basic fields like name and SKU. Examples include:
- Color: Red, Blue, Green
- Size: XS, S, M, L, XL
- Material: Cotton, Polyester, Leather
- Technical Specs: Screen size, battery life, processor type
- Certifications: Organic, Fair Trade, OEKO-TEX
EAV Pattern (Entity-Attribute-Value)
The system uses the EAV pattern to provide flexibility without changing the database schema:
- Entity: The product (e.g., "Cotton T-Shirt")
- Attribute: The attribute definition (e.g., "Color" with type SELECT)
- Value: The specific value for this product (e.g., "Red")
Benefits:
- ✅ Add new attributes without database changes
- ✅ Different products can have different attributes
- ✅ Type-safe validation (numbers, dates, booleans, etc.)
- ✅ Flexible filtering and search capabilities
- ✅ Support for single-select, multi-select, and complex data types
Attribute Types
Supported Types
The system supports 12 attribute types:
| Type | Description | Example Value | Use Case |
|---|---|---|---|
TEXT | Short text | "Cotton blend" | Materials, descriptions |
NUMBER | Numeric value | 42 | Dimensions, counts, weights |
BOOLEAN | Yes/No | true | Features (waterproof, organic) |
DATE | Calendar date | "2024-12-31" | Expiry dates, release dates |
SELECT | Single choice | "Red" | Color, size, fit |
MULTISELECT | Multiple choices | ["Red", "Blue"] | Features, certifications |
COLOR | Hex color | "#FF0000" | Color swatches |
IMAGE | Image URL | "https://..." | Additional product images |
URL | Web address | "https://..." | Video links, manuals |
EMAIL | Email address | "user@example.com" | Manufacturer contacts |
PHONE | Phone number | "+1-555-1234" | Support numbers |
JSON | Structured data | Complex specifications |
Type Capabilities
Searchable Types: TEXT, SELECT, MULTISELECT
- Can be searched using text queries
Filterable Types: BOOLEAN, SELECT, MULTISELECT, COLOR, NUMBER
- Can be used to filter product catalogs
Sortable Types: TEXT, NUMBER, DATE
- Can be used to sort product listings
API Endpoints
Base path: /api/v1/operations/attributes
1. List Attribute Types
Get all available attribute types with their metadata.
Endpoint: GET /api/v1/operations/attributes/types
Response (200 OK):
{
"data": [
{
"value": "text",
"label": "Text",
"has_options": false,
"is_searchable": true,
"is_filterable": false,
"is_sortable": true,
"input_type": "text",
"default_validation": []
},
{
"value": "select",
"label": "Single Select",
"has_options": true,
"is_searchable": true,
"is_filterable": true,
"is_sortable": false,
"input_type": "select",
"default_validation": []
},
{
"value": "number",
"label": "Number",
"has_options": false,
"is_searchable": false,
"is_filterable": true,
"is_sortable": true,
"input_type": "number",
"default_validation": ["numeric"]
}
]
}2. Create Attribute Definition
Define a new attribute template that products can use.
Endpoint: POST /api/v1/operations/attributes
Request Body (TEXT attribute):
{
"code": "material",
"name": "Material",
"label": "Product Material",
"type": "text",
"description": "Primary material composition",
"is_required": false,
"is_filterable": true,
"is_searchable": true,
"is_visible_on_frontend": true,
"sort_order": 10
}Request Body (SELECT attribute with options):
{
"code": "size",
"name": "Size",
"label": "Product Size",
"type": "select",
"description": "Available product sizes",
"options": ["XS", "S", "M", "L", "XL", "XXL"],
"is_required": true,
"is_filterable": true,
"is_searchable": true,
"is_visible_on_frontend": true,
"sort_order": 5
}Request Body (NUMBER attribute with unit):
{
"code": "thread_count",
"name": "Thread Count",
"label": "Fabric Thread Count",
"type": "number",
"unit": "threads/inch",
"description": "Fabric density measurement",
"validation_rules": ["min:100", "max:1000"],
"is_required": false,
"is_filterable": true,
"is_visible_on_frontend": true,
"sort_order": 15,
"default_value": 200
}Response (201 Created):
{
"message": "Attribute created successfully",
"data": {
"id": 5,
"code": "material",
"name": "Material",
"label": "Product Material",
"type": "text",
"description": "Primary material composition",
"options": null,
"validation_rules": null,
"is_required": false,
"is_filterable": true,
"is_searchable": true,
"is_visible_on_frontend": true,
"sort_order": 10,
"unit": null,
"default_value": null,
"created_at": "2024-01-15T10:30:00Z"
}
}Validation Rules:
code: Required, unique, max 100 chars, alphanumeric with dashes/underscores onlyname: Required, max 255 charslabel: Required, max 255 charstype: Required, must be valid attribute typeoptions: Required for SELECT and MULTISELECT typesis_required: Boolean (default: false)is_filterable: Boolean (default: false)is_searchable: Boolean (default: false)is_visible_on_frontend: Boolean (default: true)sort_order: Integer, min 0 (default: 0)
Business Rules:
- Attribute
codemust be unique and cannot be changed after creation - SELECT and MULTISELECT types require an
optionsarray - Attribute codes should use lowercase with underscores (e.g., "thread_count", "eco_friendly")
3. Update Attribute Definition
Update an existing attribute definition.
Endpoint: PUT /api/v1/operations/attributes/{attribute}
Request Body:
{
"name": "Product Size",
"label": "Choose Size",
"options": ["XS", "S", "M", "L", "XL", "XXL", "XXXL"],
"is_required": true,
"sort_order": 3
}Response (200 OK):
{
"message": "Attribute updated successfully",
"data": {
"id": 5,
"code": "size",
"name": "Product Size",
"options": ["XS", "S", "M", "L", "XL", "XXL", "XXXL"],
"is_required": true,
"sort_order": 3
}
}Important: Cannot change code or type after creation. Only metadata and options can be updated.
4. List All Attributes
Get paginated list of attribute definitions.
Endpoint: GET /api/v1/operations/attributes
Query Parameters:
page: Page number (default: 1)per_page: Items per page (default: 50, max: 100)type: Filter by attribute type (select, text, etc.)filterable: Filter to only filterable attributes (true/false)searchable: Filter to only searchable attributes (true/false)required: Filter to only required attributes (true/false)
Response (200 OK):
{
"data": [
{
"id": 1,
"code": "color",
"name": "Color",
"type": "select",
"options": ["Red", "Blue", "Green"],
"is_required": true,
"is_filterable": true,
"is_searchable": true
},
{
"id": 2,
"code": "material",
"name": "Material",
"type": "text",
"is_required": false,
"is_filterable": true,
"is_searchable": true
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 2,
"last_page": 1
}
}5. Get Single Attribute
Retrieve detailed information about a specific attribute.
Endpoint: GET /api/v1/operations/attributes/{attribute}
Response (200 OK):
{
"data": {
"id": 5,
"code": "size",
"name": "Size",
"label": "Product Size",
"type": "select",
"description": "Available product sizes",
"options": ["XS", "S", "M", "L", "XL", "XXL"],
"validation_rules": null,
"is_required": true,
"is_filterable": true,
"is_searchable": true,
"is_visible_on_frontend": true,
"sort_order": 5,
"unit": null,
"default_value": null,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T12:45:00Z",
"values_count": 147
}
}6. Delete Attribute
Delete an attribute definition.
Endpoint: DELETE /api/v1/operations/attributes/{attribute}
Response (200 OK):
{
"message": "Attribute deleted successfully"
}Business Rules:
- Cannot delete required attributes that are currently assigned to products
- Deleting an attribute removes all associated values from products
- Deleted attributes can be restored (soft delete)
7. Get Attribute Statistics
Get usage statistics for all attributes.
Endpoint: GET /api/v1/operations/attributes/statistics
Response (200 OK):
{
"data": {
"total_attributes": 12,
"by_type": {
"text": 4,
"select": 3,
"number": 2,
"boolean": 2,
"color": 1
},
"required_count": 5,
"filterable_count": 8,
"searchable_count": 6,
"most_used": [
{
"id": 1,
"code": "color",
"name": "Color",
"products_count": 247
},
{
"id": 2,
"code": "size",
"name": "Size",
"products_count": 198
}
]
}
}Assigning Attributes to Products
Setting Product Attributes
Attributes are assigned when creating or updating products. Include attribute values in the attributes field.
Create Product with Attributes:
POST /api/v1/operations/products
{
"name": "Cotton T-Shirt",
"sku": "TSHIRT-001",
"selling_price": 24.99,
"cost_price": 12.00,
"currency": "USD",
"attributes": {
"color": "Blue",
"size": "Large",
"material": "100% Cotton",
"eco_friendly": true,
"thread_count": 300
}
}Update Product Attributes:
PUT /api/v1/operations/products/123
{
"attributes": {
"color": "Red",
"size": "Medium"
}
}Response (200 OK):
{
"message": "Product updated successfully",
"data": {
"id": 123,
"name": "Cotton T-Shirt",
"attributes": {
"color": "Red",
"size": "Medium",
"material": "100% Cotton",
"eco_friendly": true,
"thread_count": 300
}
}
}Retrieving Product Attributes
Get Product with Attributes:
GET /api/v1/operations/products/123Response:
{
"data": {
"id": 123,
"name": "Cotton T-Shirt",
"sku": "TSHIRT-001",
"attributes": {
"color": "Red",
"size": "Medium",
"material": "100% Cotton",
"eco_friendly": true,
"thread_count": 300
},
"visible_attributes": [
{
"code": "color",
"name": "Color",
"label": "Product Color",
"value": "Red",
"formatted_value": "Red",
"type": "select"
},
{
"code": "thread_count",
"name": "Thread Count",
"label": "Fabric Thread Count",
"value": 300,
"formatted_value": "300 threads/inch",
"type": "number",
"unit": "threads/inch"
}
]
}
}Attribute Type Examples
TEXT Attribute
Definition:
{
"code": "product_description",
"name": "Description",
"type": "text",
"is_required": false
}Usage:
{
"attributes": {
"product_description": "Soft and comfortable cotton t-shirt"
}
}NUMBER Attribute
Definition:
{
"code": "weight_kg",
"name": "Weight",
"type": "number",
"unit": "kg",
"validation_rules": ["min:0", "max:1000"]
}Usage:
{
"attributes": {
"weight_kg": 2.5
}
}BOOLEAN Attribute
Definition:
{
"code": "organic_certified",
"name": "Organic Certified",
"type": "boolean",
"default_value": false
}Usage:
{
"attributes": {
"organic_certified": true
}
}DATE Attribute
Definition:
{
"code": "manufacture_date",
"name": "Manufacture Date",
"type": "date"
}Usage:
{
"attributes": {
"manufacture_date": "2024-01-15"
}
}Note: Use ISO 8601 format (YYYY-MM-DD).
SELECT Attribute
Definition:
{
"code": "fit",
"name": "Fit",
"type": "select",
"options": ["Slim", "Regular", "Relaxed", "Oversized"],
"is_required": true
}Usage:
{
"attributes": {
"fit": "Regular"
}
}Validation: Value must be one of the options. Invalid values will return a 422 error:
{
"errors": {
"attributes.fit": [
"Value 'Extra Slim' is not valid for attribute 'Fit'. Allowed values: Slim, Regular, Relaxed, Oversized"
]
}
}MULTISELECT Attribute
Definition:
{
"code": "care_instructions",
"name": "Care Instructions",
"type": "multiselect",
"options": [
"Machine Wash",
"Hand Wash",
"Dry Clean Only",
"Tumble Dry",
"Air Dry",
"Iron Low Heat"
]
}Usage:
{
"attributes": {
"care_instructions": [
"Machine Wash",
"Tumble Dry",
"Iron Low Heat"
]
}
}Note: Value must be an array. All values must exist in the options list.
COLOR Attribute
Definition:
{
"code": "primary_color_hex",
"name": "Primary Color",
"type": "color"
}Usage:
{
"attributes": {
"primary_color_hex": "#FF5733"
}
}Validation: Must be valid hex color (e.g., #FF5733, #000000).
URL Attribute
Definition:
{
"code": "product_video",
"name": "Product Video",
"type": "url"
}Usage:
{
"attributes": {
"product_video": "https://youtube.com/watch?v=abc123"
}
}EMAIL Attribute
Definition:
{
"code": "manufacturer_contact",
"name": "Manufacturer Contact",
"type": "email"
}Usage:
{
"attributes": {
"manufacturer_contact": "contact@manufacturer.com"
}
}JSON Attribute
Definition:
{
"code": "technical_specs",
"name": "Technical Specifications",
"type": "json"
}Usage:
{
"attributes": {
"technical_specs": {
"processor": "A17 Pro",
"ram": "8GB",
"storage": "256GB",
"camera": "48MP"
}
}
}Note: Value can be any valid JSON object or array.
Validation & Business Rules
Automatic Validation
Each attribute type has built-in validation:
TEXT:
- Maximum 255 characters
- String validation
NUMBER:
- Must be numeric
- Supports min/max validation rules
BOOLEAN:
- Must be true or false
DATE:
- Must be valid date in YYYY-MM-DD format
SELECT:
- Value must exist in options array
- Only one value allowed
MULTISELECT:
- Value must be array
- All values must exist in options array
COLOR:
- Must be valid hex color (#RRGGBB)
EMAIL:
- Must be valid email format
URL:
- Must be valid URL format
PHONE:
- Must be valid phone number format
JSON:
- Must be valid JSON
Custom Validation Rules
You can add Laravel validation rules to attributes:
Example:
{
"code": "discount_percentage",
"name": "Discount Percentage",
"type": "number",
"validation_rules": ["min:0", "max:100"],
"unit": "%"
}Valid:
{
"attributes": {
"discount_percentage": 15
}
}Invalid (422 error):
{
"attributes": {
"discount_percentage": 150
}
}Required Attributes
Mark attributes as required to enforce product data quality:
Define Required Attribute:
{
"code": "color",
"name": "Color",
"type": "select",
"is_required": true,
"options": ["Red", "Blue", "Green"]
}Validation: Products cannot be created or activated without all required attributes set.
Error Response (422):
{
"errors": {
"attributes": [
"Missing required attributes: Color, Size"
]
}
}Common Use Cases
Use Case 1: Apparel Attributes
Define Attributes:
# Size
POST /api/v1/operations/attributes
{
"code": "size",
"name": "Size",
"type": "select",
"options": ["XS", "S", "M", "L", "XL", "XXL"],
"is_required": true,
"is_filterable": true
}
# Color
POST /api/v1/operations/attributes
{
"code": "color",
"name": "Color",
"type": "select",
"options": ["Black", "White", "Navy", "Gray", "Red"],
"is_required": true,
"is_filterable": true
}
# Material
POST /api/v1/operations/attributes
{
"code": "material",
"name": "Material",
"type": "text",
"is_searchable": true
}Create Product:
POST /api/v1/operations/products
{
"name": "Classic Cotton T-Shirt",
"sku": "TSHIRT-001",
"selling_price": 24.99,
"attributes": {
"size": "L",
"color": "Navy",
"material": "100% Cotton",
"care_instructions": ["Machine Wash", "Tumble Dry"]
}
}Use Case 2: Electronics Specifications
Define JSON Attribute:
POST /api/v1/operations/attributes
{
"code": "tech_specs",
"name": "Technical Specifications",
"type": "json"
}Create Product:
POST /api/v1/operations/products
{
"name": "Smartphone Pro",
"sku": "PHONE-001",
"selling_price": 999.00,
"attributes": {
"tech_specs": {
"processor": "Apple A17 Pro",
"ram": "8GB",
"storage": "256GB",
"display": "6.1\" Super Retina XDR",
"camera": "48MP Main + 12MP Ultra Wide",
"battery": "3877 mAh",
"connectivity": "5G, WiFi 6E, Bluetooth 5.3"
}
}
}Use Case 3: Product Certifications
Define MULTISELECT Attribute:
POST /api/v1/operations/attributes
{
"code": "certifications",
"name": "Certifications",
"type": "multiselect",
"options": [
"Organic Certified",
"Fair Trade",
"GOTS",
"OEKO-TEX",
"B Corp"
]
}Create Product:
POST /api/v1/operations/products
{
"name": "Organic Cotton Sheet Set",
"sku": "SHEET-001",
"selling_price": 149.99,
"attributes": {
"certifications": [
"Organic Certified",
"Fair Trade",
"GOTS"
]
}
}Best Practices
1. Use Consistent Attribute Codes
Always use lowercase with underscores:
✅ "product_color"
✅ "thread_count"
✅ "eco_friendly"
❌ "ProductColor"
❌ "Thread-Count"
❌ "EcoFriendly"2. Define All Options for SELECT Types
✅ Correct:
{
"type": "select",
"options": ["Red", "Blue", "Green", "Black", "White"]
}
❌ Wrong:
{
"type": "select",
"options": null
}3. Use Appropriate Types
Match the attribute type to the data:
✅ Use BOOLEAN for yes/no:
{
"attributes": {
"waterproof": true
}
}
❌ Don't use TEXT for boolean data:
{
"attributes": {
"waterproof": "yes"
}
}4. Mark Important Attributes as Required
Ensure data quality by requiring essential attributes:
{
"code": "size",
"is_required": true
}5. Make Attributes Filterable for Catalog
Enable filtering for attributes used in product browsing:
{
"code": "color",
"is_filterable": true,
"is_searchable": true
}6. Use Frontend Visibility Appropriately
Hide internal attributes from frontend display:
{
"code": "supplier_code",
"is_visible_on_frontend": false
}7. Order Attributes Logically
Use sort_order to control display sequence:
{
"code": "color",
"sort_order": 1
},
{
"code": "size",
"sort_order": 2
},
{
"code": "material",
"sort_order": 3
}Troubleshooting
Error: "Validation failed for attribute"
Error Response:
{
"errors": {
"attributes.size": [
"Value 'XXL' is not valid for attribute 'Size'. Allowed values: XS, S, M, L, XL"
]
}
}Solution: Add the value to attribute options:
PUT /api/v1/operations/attributes/5
{
"options": ["XS", "S", "M", "L", "XL", "XXL"]
}Error: "Missing required attributes"
Error Response:
{
"errors": {
"attributes": [
"Missing required attributes: Color, Size"
]
}
}Solution: Include all required attributes in the request:
{
"attributes": {
"color": "Red",
"size": "Large"
}
}Error: "Options required for SELECT type"
Error Response:
{
"errors": {
"options": [
"Options are required for SELECT and MULTISELECT attribute types"
]
}
}Solution: Always provide options for SELECT/MULTISELECT:
{
"type": "select",
"options": ["Option 1", "Option 2", "Option 3"]
}Related Documentation
- Product Variants Guide - Using attributes for variant generation
- Pricing Strategy Guide - Product pricing configuration
- Product Lifecycle - Product management workflow