Introduction
Welcome to Velou!
The Velou REST API allows you interact directly with Velou to efficiently index your products and perform lightning fast, highly relevant search through your products catalog.
Ready to see it in action? Let's get going!
Getting Started
Velou API provides you with a variety of endpoints to craft intuitive, relevant and powerful search experiences to help your shopper's quickly find what they are looking for.
Formats
All API requests should be JSON encoded as UTF-8. The body of POST and PUT requests must be either a JSON object or a JSON array and their Content-Type header should be set to application/json. The body of responses is always a JSON object, and their content type is always application/json.
Versioning
API releases are versioned using a two part versioning scheme: {major version}.{minor version}. We broadly follow Semantic Versioning principles when versioning the API. The major version number is incremented when a backwards-incompatible change occurs. Minor version numbers are incremented when backwards-compatible changes occur.
Velou API versions are explicitly declared in the URL that your application calls: https://{API_HOST}/{version}
There are several supported versions of the APIs available, and you specify the version that you want to use by substituting the version name in the URL.
| Version | Release Date | Changelog |
|---|---|---|
| 0.9 | March 5, 2019 | Beta release |
| 1.0 | April 14, 2019 | Initial stable version |
| 1.1 | June 25, 2019 | Introduced facets support |
| 1.2 | October 10, 2019 | Event tracking improvements (Usage Analytics) |
| 1.3 | November 15, 2021 | Introducing new attributes: relatedIds, fitInformation, media.highResUrl, media.altText and collections |
| 1.4 | January 23, 2022 | Incorporation of the analytics events for “add to cart”, and “promotions” |
| 1.5 | September 18, 2023 | Modification for analytics to support multiple regions and languages |
| 1.6 | March 25, 2024 | Incorporation of the analytics events for “complete the look” |
| 1.7 | December 23, 2024 | Modified exporter response to include display names, synonyms, and trends |
| 1.8 | June 6, 2025 | Standardized identifier naming by capitalizing the first letter of UserId and SessionId |
| 1.9 | October 10, 2025 | Revised Public Indexing API definitions, including updates to the tags array |
| 2.0 | February 17, 2026 | Added new v2/products endpoint with updated validations including variationId checks |
Authentication
Accessing the Velou API requires the following; these credentials will be provided to you by Velou once your account is established.
- Store ID: Unique identifier to represent your store at Velou.
- Velou API Key: Secure API keys to prevent unauthorized access to your data. There are three different types of keys that you can apply depending your needs:
- admin – Admin API Key has permissions to perform write/read operations such as products catalog indexing. This key should be only used in server-side applications and should never be shared with any third-party or exposed in client-side applications.
- search - Search API Key has read-only permissions to perform search-related activity. This key is commonly used in the client-side applications to communicate directly with Velou API from the web browser.
- analytics - Analytics API key is used to track important events of shopper's browser session. This key is commonly used in the client-side applications to communicate directly with Velou API from the web browser.
Velou API uses key-based authentication over SSL. All requests to Velou API require HTTP headers X-Velou-Store-ID and X-Velou-API-Key for authentication purposes.
Indexing
Add/Update Product
Velou provides an API for indexing products in your catalog. Use these endpoints to add new products or update existing ones. The API is asynchronous - you'll receive a unique task identifier to track the indexing status.
Consider invoking this API whenever:
- A new product is added to your catalog
- Product information is updated (price, availability, description, etc.)
- Product variations or SKUs change
Available Endpoints
Velou supports two API versions for product indexing:
POST https://{API_HOST}/productsPOST https://{API_HOST}/v2/products
Required Headers:
X-Velou-API-Key: <admin-api-key>Content-Type: application/json
Note: Both endpoints share the same request/response format and functionality. Choose the version that best fits your integration needs.
Version 1.0 Endpoint Details
Endpoint: POST https://{API_HOST}/products
Required Fields
Every product indexing request must include:
id- Unique product identifier (1-200 characters)url- Product page URL (1-2000 characters, valid URI format)skus- Array of at least one SKU (1-200 items)skus[].price- Each SKU must have a price (number >= 0)
All other fields are optional but highly recommended for optimal search relevance and user experience.
Quick Start
Minimal Request (required fields only)
{
"id": "PROD123",
"url": "https://mystore.com/products/red-dress",
"skus": [
{
"price": 79.99
}
]
}
Sample Response
{
"taskId": "4fe09ba9f54e81f98e18bce903521981e71fad48"
}
Complete Product Object
Top-Level Fields
| Field | Type | Required | Length/Range | Description |
|---|---|---|---|---|
id |
String | Yes | 1-200 chars | Unique product identifier from your system |
url |
String | Yes | 1-2000 chars | Product page URL (must be valid URI format) |
skus |
Array | Yes | 1-200 items | Product SKU variations (see SKU Object below) |
name |
String | No | 1-500 chars | Product display name |
brand |
String | No | 1-200 chars | Brand or manufacturer name |
slug |
String | No | 1-300 chars | URL-friendly product identifier |
description |
String | No | 1-10,000 chars | Detailed product description (HTML allowed) |
categories |
Array[String] | No | 1-100 items, 1-200 chars each | Product categories/hierarchy |
collections |
Array[String] | No | 1-100 items, 1-200 chars each | Collection/group membership |
gender |
String | No | Enum | Men, Women, or Unisex |
ageGroup |
String | No | Enum | Adults, Teens, or Kids |
features |
Array[String] | No | 1-50 items, 1-2000 chars each | Key features/bullet points |
tags |
Array[String] | No | 1-2000 items, 1-1000 chars each | Product tags (format: tagType:value) |
customUserTags |
Array[String] | No | 1-200 items, 1-200 chars each | Custom tags (format: tagType:value) |
customUserData |
Object | No | Max 30 keys | Custom attributes (keys: ^[a-zA-z][a-zA-Z0-9]{0,30}$) |
relatedIds |
Array[String] | No | 0-1000 items, 1-200 chars each | IDs of related products |
sortOrder |
Integer | No | - | Custom sort order |
arrivalDateTs |
Integer | No | - | Arrival date (UNIX timestamp in ms) |
media |
Array[Object] | No | 1-150 items | Product images/videos (see Media Object) |
variations |
Array[Object] | No | 1-50 items | Color/style variations (see Variation Object) |
fitInformation |
Array[String] | No | 1-20 items, 1-200 chars each | Fit/sizing information |
popularity |
Object | No | - | Popularity metrics (see Popularity Object) |
Nested Objects
SKU Object
Example
{
"price": 79.99,
"promoPrice": 59.99,
"variationId": "red",
"size": "Medium",
"availability": "InStock",
"inventoryQuantity": 45
}
Each item in the skus array represents a product variant (size, color combination, etc.).
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
price |
Number | Yes | >= 0 | Current selling price |
promoPrice |
Number | No | >= 0 | Promotional/sale price |
variationId |
String | No | 1-200 chars | Links to variations[].id |
size |
String | No | 1-1000 chars | Size designation (e.g., "Small", "10", "XL") |
initialPrice |
Number | No | >= 0 | Original/MSRP price before any discounts |
estimatedRetailPrice |
Number | No | >= 0 | Manufacturer's suggested retail price |
inventoryQuantity |
Integer | No | >= 0 | Current stock quantity |
availability |
String | No | Enum | See availability values below |
condition |
Array[String] | No | 1-20 items, 1-200 chars each | Product condition (e.g., "New", "Refurbished") |
tags |
Array[String] | No | 1-100 items, 1-200 chars each | SKU-specific tags (format: tagType:value) |
Availability Values:
Discontinued- No longer availableInStock- Currently availableInStoreOnly- Only available in physical storesLimitedAvailability- Low stockOnlineOnly- Only available onlineOutOfStock- Temporarily unavailablePreOrder- Available for pre-orderPreSale- Available for pre-saleSoldOut- Permanently out of stockOutOfStockPurchasable- Can be purchased while out of stock
Media Object
Example
{
"url": "https://cdn.mystore.com/products/dress-red-500.jpg",
"highResUrl": "https://cdn.mystore.com/products/dress-red-2000.jpg",
"altText": "Woman wearing red floral dress with V-neck and long sleeves",
"variationId": "red"
}
Each item in the media array represents an image or video.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
url |
String | Yes | 1-2000 chars, URI format | Image/video URL |
highResUrl |
String | No | 1-2000 chars, URI format | High-resolution version URL |
altText |
String | No | 1-500 chars | Accessibility description |
variationId |
String | No | 1-200 chars | Links to variations[].id |
Variation Object
Example
{
"id": "red",
"name": "Red",
"swatch": "https://cdn.mystore.com/swatches/red.png",
"url": "https://mystore.com/products/floral-dress?color=red"
}
Each item in the variations array represents a color or style variant.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id |
String | Yes | 1-200 chars | Unique variation identifier |
name |
String | Yes | 1-150 chars | Variation name (e.g., "Red", "Navy Blue") |
swatch |
String | No | 1-500 chars, URI format | Color swatch image URL |
url |
String | No | 1-2000 chars | Variation-specific product URL |
productId |
String | No | 1-200 chars | Variation product identifier |
productName |
String | No | 1-500 chars | Variation-specific product name |
relatedIds |
Array[String] | No | 0-300 items, 1-200 chars each | Related variation IDs |
Popularity Object
Type: STAR (Star Rating System)
{
"type": "STAR",
"data": {
"overallRating": 4.3, // Required: Number >= 0
"maxRating": 5, // Required: Number >= 0
"reviewCount": 260, // Required: Integer >= 0
"ratingSummary": [ // Optional: Array, 0-10 items
{
"rating": 5, // Required: Integer >= 1
"count": 120 // Required: Integer >= 0
},
{
"rating": 4,
"count": 85
}
]
}
}
Type: LIKES (Like/Favorite Count)
{
"type": "LIKES",
"data": {
"favLikeCount": 1250 // Required: Integer >= 0
}
}
Type: THUMBS (Thumbs Up/Down)
{
"type": "THUMBS",
"data": {
"thumbsUpCount": 89, // Required: Integer >= 0
"thumbsDownCount": 12 // Required: Integer >= 0
}
}
The popularity object structure depends on the type field.
Special Format Requirements
Tag Format
Tags and custom user tags must follow the tagType:value format:
Valid Example
"tags": [
"color:Red",
"neckline:V-Neck",
"fit_type:Relaxed",
"material:Cotton",
"sleeve_length:Long"
]
Invalid Example
"tags": [
"Red", // Missing tag type
"color-Red", // Wrong separator
"neckline: V-Neck" // Space before colon
]
Applies to: tags[], customUserTags[], skus[].tags[]
Custom User Data Keys
Custom user data object keys must match the pattern: ^[a-zA-z][a-zA-Z0-9]{0,30}$
Valid Example
"customUserData": {
"seasonalCollection": ["Summer2025", "Resort"],
"exclusiveRetailer": ["NordstromExclusive"],
"certifications": ["Organic", "FairTrade"]
}
Invalid Example
"customUserData": {
"seasonal-collection": [...], // Hyphen not allowed
"1stPlace": [...], // Cannot start with number
"_private": [...] // Cannot start with underscore
}
Complete Example
Full Product Request
{
"id": "1636730011711",
"url": "https://demostore.com/products/floral-red-dress",
"name": "Floral Red Dress - V-Neck Sleeveless Summer Collection",
"brand": "Dress Forum",
"slug": "floral-red-dress-v-neck-sleeveless",
"description": "Ever comfortable and chic, the classic shift gains a fresh feeling from crisp, colorful crepe. Perfect for summer occasions.",
"features": [
"34 1/2\" length (size Medium)",
"Exposed back-zip closure",
"97% polyester, 3% spandex",
"Hand wash cold, dry flat",
"Imported"
],
"categories": [
"Women",
"Clothing",
"Dresses",
"Casual Dresses"
],
"collections": [
"Summer 2025",
"Resort Collection"
],
"gender": "Women",
"ageGroup": "Adults",
"relatedIds": ["1636730011712", "1636730011713"],
"arrivalDateTs": 1625097600000,
"variations": [
{
"id": "red",
"name": "Red",
"swatch": "https://demostore.com/images/swatches/red.png",
"url": "https://demostore.com/products/floral-red-dress?color=red"
},
{
"id": "black",
"name": "Black",
"swatch": "https://demostore.com/images/swatches/black.png",
"url": "https://demostore.com/products/floral-red-dress?color=black"
}
],
"media": [
{
"url": "https://demostore.com/images/products/l/1636730011711-red-front.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-red-front.jpg",
"altText": "Front view of red floral dress with V-neck and sleeveless design",
"variationId": "red"
},
{
"url": "https://demostore.com/images/products/l/1636730011711-red-back.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-red-back.jpg",
"altText": "Back view showing exposed zipper closure",
"variationId": "red"
},
{
"url": "https://demostore.com/images/products/l/1636730011711-black-front.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-black-front.jpg",
"altText": "Front view of black floral dress with V-neck and sleeveless design",
"variationId": "black"
}
],
"skus": [
{
"price": 79.99,
"promoPrice": 59.99,
"initialPrice": 99.99,
"variationId": "red",
"size": "Small",
"availability": "InStock",
"inventoryQuantity": 25
},
{
"price": 79.99,
"promoPrice": 59.99,
"variationId": "red",
"size": "Medium",
"availability": "InStock",
"inventoryQuantity": 40
},
{
"price": 79.99,
"variationId": "red",
"size": "Large",
"availability": "LimitedAvailability",
"inventoryQuantity": 3
},
{
"price": 79.99,
"variationId": "black",
"size": "Small",
"availability": "InStock",
"inventoryQuantity": 18
}
],
"tags": [
"color:Red",
"neckline:V-Neck",
"fit_type:Relaxed",
"sleeve_length:Sleeveless",
"occasion:Casual",
"season:Summer",
"pattern:Floral"
],
"customUserTags": [
"collection:Resort2025",
"trending:SummerEssentials"
],
"fitInformation": [
"True to size",
"Model is 5'9\" and wearing size Small",
"Relaxed fit through body"
],
"popularity": {
"type": "STAR",
"data": {
"overallRating": 4.3,
"maxRating": 5,
"reviewCount": 260,
"ratingSummary": [
{ "rating": 5, "count": 140 },
{ "rating": 4, "count": 80 },
{ "rating": 3, "count": 25 },
{ "rating": 2, "count": 10 },
{ "rating": 1, "count": 5 }
]
}
}
}
Sample Response
{
"taskId": "4fe09ba9f54e81f98e18bce903521981e71fad48"
}
Use the taskId to track indexing status via the Task Tracking endpoint.
Error Responses
400 Bad Request - Validation Error
When validation fails, you'll receive a detailed error response:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "url",
"message": "url should be a string (minLength=1, maxLength=2000) and should conform to valid URI format",
"value": "not-a-valid-url"
},
{
"field": "skus",
"message": "skus should be an array of valid Sku objects (minItems=1, maxItems=200)",
"value": []
}
]
}
}
Common Validation Errors
Missing Required Fields
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Missing required fields: id, url, skus"
}
}
Field Too Long
{
"error": {
"code": "VALIDATION_ERROR",
"message": "name should be a string (minLength=1, maxLength=500)",
"field": "name",
"actualLength": 650
}
}
Invalid Enum Value
{
"error": {
"code": "VALIDATION_ERROR",
"message": "gender should be a string (allowed_values=Men|Women|Unisex)",
"field": "gender",
"value": "Male"
}
}
Invalid Tag Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "tags should conform to 'tagType:tag' format",
"details": [
{
"field": "tags[0]",
"value": "Red",
"expected": "color:Red"
}
]
}
}
Array Size Violation
{
"error": {
"code": "VALIDATION_ERROR",
"message": "skus should be an array of valid Sku objects (minItems=1, maxItems=200)",
"field": "skus",
"actualItems": 0,
"expectedRange": "1-200"
}
}
401 Unauthorized (Invalid or missing API key)
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key or insufficient permissions. Admin API key required."
}
}
Best Practices For Product Indexing
Data Quality
- Include as much data as possible: While many fields are optional, providing comprehensive product information significantly improves search relevance and user experience
- Keep data current: Update prices, availability, and inventory in real-time or near real-time
- Use consistent formatting: Maintain consistent naming conventions for brands, categories, and tags
- Provide high-quality media: Include multiple images for each variation with descriptive alt text
Field Usage
URLs (up to 2000 characters):
- Use absolute URLs, not relative paths
- Include tracking parameters (UTM codes, session IDs, etc.) as needed
- Ensure URLs are properly URL-encoded
- Example: https://store.com/products/dress?utm_source=email&color=red
Product Names (up to 500 characters):
- Include key specifications and descriptors
- Front-load important information
- Example: "Nike Women's Air Zoom Pegasus 38 - Breathable Mesh Running Shoes - Black/White"
IDs (up to 200 characters):
- Supports composite keys, hierarchical identifiers, UUIDs
- Use consistent ID structure across your catalog
- Example: "store_123_category_shoes_product_abc789"
Descriptions (up to 10,000 characters): - Be comprehensive - include materials, care instructions, features - HTML formatting is supported - Break into paragraphs for readability
Arrays
Categories:
- Provide full category hierarchy: ["Women", "Clothing", "Dresses", "Casual Dresses"]
- Use 1-100 items, each up to 200 characters
- Consistent naming improves faceted search
Tags:
- Always use tagType:value format: "color:Red" not "Red"
- Use consistent tag types: color, size, material, style, occasion
- Supports 1-2000 tags, each up to 1000 characters
- More tags = better discoverability
Media:
- Provide images for all variations
- Use variationId to link images to color/style variants
- Include descriptive altText for accessibility (up to 500 chars)
- High-res URLs improve image search capabilities
Features: - Use for bullet points and key highlights - Each feature can be up to 2000 characters - Include specifications, materials, dimensions, care instructions
Variations & SKUs
Linking Variations:
- Define variations with unique IDs: {id: "red", name: "Red"}
- Link SKUs to variations: {variationId: "red", size: "Small"}
- Link media to variations: {url: "...", variationId: "red"}
- Ensures proper filtering and display
SKU Management:
- Keep availability status current
- Update inventoryQuantity regularly
- Use promoPrice for sale pricing
- Include size information when applicable
Performance
- Request Size: Keep individual requests under 1MB for optimal performance
- Bulk Updates: Use multiple API calls rather than one massive payload
- Timing: Consider batching updates during low-traffic periods
- Rate Limiting: Respect API rate limits (contact Velou if you need higher limits)
Error Handling For Product Indexing
- Retry Logic: Implement exponential backoff for failed requests
- Validation: Pre-validate data before sending to reduce errors
- Logging: Log all validation errors for analysis
- Monitoring: Track task completion via the Task Tracking endpoint
Quick Reference Card
Required Fields
id(1-200 chars)url(1-2000 chars, URI format)skus[](1-200 items)skus[].price(number >= 0)
Common Field Limits
- URLs: 2000 characters (product, media, variations)
- Product Name: 500 characters
- All IDs: 200 characters
- Description: 10,000 characters
- Brand: 200 characters
- Slug: 300 characters
- Categories/Collections: 200 characters each
- Alt Text: 500 characters
Enum Fields
- gender:
Men|Women|Unisex - ageGroup:
Adults|Teens|Kids - availability:
InStock|OutOfStock|PreOrder|LimitedAvailability| etc. - popularity.type:
STAR|LIKES|THUMBS
Array Limits
- skus: 1-200 items (required)
- media: 1-150 items
- variations: 1-50 items
- tags: 1-2000 items
- customUserTags: 1-200 items
- categories: 1-100 items
- collections: 1-100 items
- features: 1-50 items
Special Formats
- Tags: Must use
tagType:valueformat (e.g.,"color:Red") - URLs: Must be valid URI format
- Numbers: Must be >= 0 for prices, ratings, counts
- customUserData keys:
^[a-zA-z][a-zA-Z0-9]{0,30}$
Version 2.0 Endpoint Details
Endpoint: POST https://{API_HOST}/v2/products
Required Fields
Every product indexing request must include:
id- Unique product identifier (1-200 characters)url- Product page URL (1-2000 characters, valid URI format)skus- Array of at least one SKU (1-300 items)skus[].price- Each SKU must have a price (number >= 0)skus[].variationId- SKU variation identifier (required, 1–200 characters)
variations- Array of product variations (1–50 items if SKUs use variationId)- All variationId values from SKUs must exist in this array
All other fields are optional but highly recommended for optimal search relevance and user experience.
Quick Start
Minimal Request (required fields only)
{
"id": "PROD123",
"url": "https://mystore.com/products/red-dress",
"skus": [
{
"variationId": "red",
"price": 79.99
}
],
"variations": [
{
"id": "red",
"name": "Red"
}
]
}
Sample Response
{
"taskId": "4fe09ba9f54e81f98e18bce903521981e71fad48"
}
Complete Product Object
Top-Level Fields
| Field | Type | Required | Length/Range | Description |
|---|---|---|---|---|
id |
String | Yes | 1-200 chars | Unique product identifier from your system |
url |
String | Yes | 1-2000 chars | Product page URL (must be valid URI format) |
skus |
Array | Yes | 1-300 items | Product SKU variations (see SKU Object below) |
name |
String | No | 1-500 chars | Product display name |
brand |
String | No | 1-200 chars | Brand or manufacturer name |
slug |
String | No | 1-300 chars | URL-friendly product identifier |
description |
String | No | 1-10,000 chars | Detailed product description (HTML allowed) |
categories |
Array[String] | No | 1-100 items, 1-200 chars each | Product categories/hierarchy |
collections |
Array[String] | No | 1-100 items, 1-200 chars each | Collection/group membership |
gender |
String | No | Enum | Men, Women, or Unisex |
ageGroup |
String | No | Enum | Adults, Teens, or Kids |
features |
Array[String] | No | 1-50 items, 1-2000 chars each | Key features/bullet points |
tags |
Array[String] | No | 1-2000 items, 1-1000 chars each | Product tags (format: tagType:value) |
customUserTags |
Array[String] | No | 1-200 items, 1-200 chars each | Custom tags (format: tagType:value) |
customUserData |
Object | No | Max 30 keys | Custom attributes (keys: ^[a-zA-z][a-zA-Z0-9]{0,30}$) |
relatedIds |
Array[String] | No | 0-1000 items, 1-200 chars each | IDs of related products |
sortOrder |
Integer | No | - | Custom sort order |
arrivalDateTs |
Integer | No | - | Arrival date (UNIX timestamp in ms) |
media |
Array[Object] | No | 1-150 items | Product images/videos (see Media Object) |
variations |
Array[Object] | Yes | 1-50 items | Color/style variations (see Variation Object) |
fitInformation |
Array[String] | No | 1-20 items, 1-200 chars each | Fit/sizing information |
popularity |
Object | No | - | Popularity metrics (see Popularity Object) |
Nested Objects
SKU Object
Example
{
"price": 79.99,
"promoPrice": 59.99,
"variationId": "red",
"size": "Medium",
"availability": "InStock",
"inventoryQuantity": 45
}
Each item in the skus array represents a product variant (size, color combination, etc.).
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
price |
Number | Yes | >= 0 | Current selling price |
promoPrice |
Number | No | >= 0 | Promotional/sale price |
variationId |
String | Yes | 1-200 chars | Links to variations[].id |
size |
String | No | 1-1000 chars | Size designation (e.g., "Small", "10", "XL") |
initialPrice |
Number | No | >= 0 | Original/MSRP price before any discounts |
estimatedRetailPrice |
Number | No | >= 0 | Manufacturer's suggested retail price |
inventoryQuantity |
Integer | No | >= 0 | Current stock quantity |
availability |
String | No | Enum | See availability values below |
condition |
Array[String] | No | 1-20 items, 1-200 chars each | Product condition (e.g., "New", "Refurbished") |
tags |
Array[String] | No | 1-100 items, 1-200 chars each | SKU-specific tags (format: tagType:value) |
Availability Values:
Discontinued- No longer availableInStock- Currently availableInStoreOnly- Only available in physical storesLimitedAvailability- Low stockOnlineOnly- Only available onlineOutOfStock- Temporarily unavailablePreOrder- Available for pre-orderPreSale- Available for pre-saleSoldOut- Permanently out of stockOutOfStockPurchasable- Can be purchased while out of stock
Media Object
Example
{
"url": "https://cdn.mystore.com/products/dress-red-500.jpg",
"highResUrl": "https://cdn.mystore.com/products/dress-red-2000.jpg",
"altText": "Woman wearing red floral dress with V-neck and long sleeves",
"variationId": "red"
}
Each item in the media array represents an image or video.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
url |
String | Yes | 1-2000 chars, URI format | Image/video URL |
highResUrl |
String | No | 1-2000 chars, URI format | High-resolution version URL |
altText |
String | No | 1-500 chars | Accessibility description |
variationId |
String | No | 1-200 chars | Links to variations[].id |
Variation Object
Each item in the variations array represents a color or style variant.
Example
{
"id": "red",
"name": "Red",
"swatch": "https://cdn.mystore.com/swatches/red.png",
"url": "https://mystore.com/products/floral-dress?color=red"
}
Type: STAR (Star Rating System)
{
"type": "STAR",
"data": {
"overallRating": 4.3, // Required: Number >= 0
"maxRating": 5, // Required: Number >= 0
"reviewCount": 260, // Required: Integer >= 0
"ratingSummary": [ // Optional: Array, 0-10 items
{
"rating": 5, // Required: Integer >= 1
"count": 120 // Required: Integer >= 0
},
{
"rating": 4,
"count": 85
}
]
}
}
Type: LIKES (Like/Favorite Count)
{
"type": "LIKES",
"data": {
"favLikeCount": 1250 // Required: Integer >= 0
}
}
Type: THUMBS (Thumbs Up/Down)
{
"type": "THUMBS",
"data": {
"thumbsUpCount": 89, // Required: Integer >= 0
"thumbsDownCount": 12 // Required: Integer >= 0
}
}
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id |
String | Yes | 1-200 chars | Unique variation identifier |
name |
String | Yes | 1-150 chars | Variation name (e.g., "Red", "Navy Blue") |
swatch |
String | No | 1-500 chars, URI format | Color swatch image URL |
url |
String | No | 1-2000 chars | Variation-specific product URL |
productId |
String | No | 1-200 chars | Variation product identifier |
productName |
String | No | 1-500 chars | Variation-specific product name |
relatedIds |
Array[String] | No | 0-300 items, 1-200 chars each | Related variation IDs |
Popularity Object
The popularity object structure depends on the type field.
Special Format Requirements
Tag Format
Tags and custom user tags must follow the tagType:value format:
Valid Example
"tags": [
"color:Red",
"neckline:V-Neck",
"fit_type:Relaxed",
"material:Cotton",
"sleeve_length:Long"
]
Invalid Example
"tags": [
"Red", // Missing tag type
"color-Red", // Wrong separator
"neckline: V-Neck" // Space before colon
]
Applies to: tags[], customUserTags[], skus[].tags[]
Custom User Data Keys
Custom user data object keys must match the pattern: ^[a-zA-z][a-zA-Z0-9]{0,30}$
Valid Example
"customUserData": {
"seasonalCollection": ["Summer2025", "Resort"],
"exclusiveRetailer": ["NordstromExclusive"],
"certifications": ["Organic", "FairTrade"]
}
Invalid Example
"customUserData": {
"seasonal-collection": [...], // Hyphen not allowed
"1stPlace": [...], // Cannot start with number
"_private": [...] // Cannot start with underscore
}
Complete Example
Full Product Request
{
"id": "1636730011711",
"url": "https://demostore.com/products/floral-red-dress",
"name": "Floral Red Dress - V-Neck Sleeveless Summer Collection",
"brand": "Dress Forum",
"slug": "floral-red-dress-v-neck-sleeveless",
"description": "Ever comfortable and chic, the classic shift gains a fresh feeling from crisp, colorful crepe. Perfect for summer occasions.",
"features": [
"34 1/2\" length (size Medium)",
"Exposed back-zip closure",
"97% polyester, 3% spandex",
"Hand wash cold, dry flat",
"Imported"
],
"categories": [
"Women",
"Clothing",
"Dresses",
"Casual Dresses"
],
"collections": [
"Summer 2025",
"Resort Collection"
],
"gender": "Women",
"ageGroup": "Adults",
"relatedIds": ["1636730011712", "1636730011713"],
"arrivalDateTs": 1625097600000,
"variations": [
{
"id": "red",
"name": "Red",
"swatch": "https://demostore.com/images/swatches/red.png",
"url": "https://demostore.com/products/floral-red-dress?color=red"
},
{
"id": "black",
"name": "Black",
"swatch": "https://demostore.com/images/swatches/black.png",
"url": "https://demostore.com/products/floral-red-dress?color=black"
}
],
"media": [
{
"url": "https://demostore.com/images/products/l/1636730011711-red-front.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-red-front.jpg",
"altText": "Front view of red floral dress with V-neck and sleeveless design",
"variationId": "red"
},
{
"url": "https://demostore.com/images/products/l/1636730011711-red-back.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-red-back.jpg",
"altText": "Back view showing exposed zipper closure",
"variationId": "red"
},
{
"url": "https://demostore.com/images/products/l/1636730011711-black-front.jpg",
"highResUrl": "https://demostore.com/images/products/xl/1636730011711-black-front.jpg",
"altText": "Front view of black floral dress with V-neck and sleeveless design",
"variationId": "black"
}
],
"skus": [
{
"price": 79.99,
"promoPrice": 59.99,
"initialPrice": 99.99,
"variationId": "red",
"size": "Small",
"availability": "InStock",
"inventoryQuantity": 25
},
{
"price": 79.99,
"promoPrice": 59.99,
"variationId": "red",
"size": "Medium",
"availability": "InStock",
"inventoryQuantity": 40
},
{
"price": 79.99,
"variationId": "red",
"size": "Large",
"availability": "LimitedAvailability",
"inventoryQuantity": 3
},
{
"price": 79.99,
"variationId": "black",
"size": "Small",
"availability": "InStock",
"inventoryQuantity": 18
}
],
"tags": [
"color:Red",
"neckline:V-Neck",
"fit_type:Relaxed",
"sleeve_length:Sleeveless",
"occasion:Casual",
"season:Summer",
"pattern:Floral"
],
"customUserTags": [
"collection:Resort2025",
"trending:SummerEssentials"
],
"fitInformation": [
"True to size",
"Model is 5'9\" and wearing size Small",
"Relaxed fit through body"
],
"popularity": {
"type": "STAR",
"data": {
"overallRating": 4.3,
"maxRating": 5,
"reviewCount": 260,
"ratingSummary": [
{ "rating": 5, "count": 140 },
{ "rating": 4, "count": 80 },
{ "rating": 3, "count": 25 },
{ "rating": 2, "count": 10 },
{ "rating": 1, "count": 5 }
]
}
}
}
Sample Response
{
"taskId": "4fe09ba9f54e81f98e18bce903521981e71fad48"
}
Use the taskId to track indexing status via the Task Tracking endpoint.
Error Responses
400 Bad Request - Validation Error
When validation fails, you'll receive a detailed error response:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "url",
"message": "url should be a string (minLength=1, maxLength=2000) and should conform to valid URI format",
"value": "not-a-valid-url"
},
{
"field": "skus",
"message": "skus should be an array of valid Sku objects (minItems=1, maxItems=300)",
"value": []
}
]
}
}
Common Validation Errors
Missing Required Fields
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Missing required fields: id, url, skus"
}
}
Field Too Long
{
"error": {
"code": "VALIDATION_ERROR",
"message": "name should be a string (minLength=1, maxLength=500)",
"field": "name",
"actualLength": 650
}
}
Invalid Enum Value
{
"error": {
"code": "VALIDATION_ERROR",
"message": "gender should be a string (allowed_values=Men|Women|Unisex)",
"field": "gender",
"value": "Male"
}
}
Invalid Tag Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "tags should conform to 'tagType:tag' format",
"details": [
{
"field": "tags[0]",
"value": "Red",
"expected": "color:Red"
}
]
}
}
Array Size Violation
{
"error": {
"code": "VALIDATION_ERROR",
"message": "skus should be an array of valid Sku objects (minItems=1, maxItems=300)",
"field": "skus",
"actualItems": 0,
"expectedRange": "1-300"
}
}
401 Unauthorized (Invalid or missing API key)
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key or insufficient permissions. Admin API key required."
}
}
Variation ID Mismatch (Return when the variations array is missing)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "variations array must be present and contain ids matching all variationId values from skus"
}
}
VariationId Within Skus Not Found in Variations (Return when a variationId provided within skus does not match any id in the variations array)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "variationId values [Red] in skus must match an id in variations array"
}
}
Best Practices For Product Indexing
Data Quality
- Include as much data as possible: While many fields are optional, providing comprehensive product information significantly improves search relevance and user experience
- Keep data current: Update prices, availability, and inventory in real-time or near real-time
- Use consistent formatting: Maintain consistent naming conventions for brands, categories, and tags
- Provide high-quality media: Include multiple images for each variation with descriptive alt text
Field Usage
URLs (up to 2000 characters):
- Use absolute URLs, not relative paths
- Include tracking parameters (UTM codes, session IDs, etc.) as needed
- Ensure URLs are properly URL-encoded
- Example: https://store.com/products/dress?utm_source=email&color=red
Product Names (up to 500 characters):
- Include key specifications and descriptors
- Front-load important information
- Example: "Nike Women's Air Zoom Pegasus 38 - Breathable Mesh Running Shoes - Black/White"
IDs (up to 200 characters):
- Supports composite keys, hierarchical identifiers, UUIDs
- Use consistent ID structure across your catalog
- Example: "store_123_category_shoes_product_abc789"
Descriptions (up to 10,000 characters): - Be comprehensive - include materials, care instructions, features - HTML formatting is supported - Break into paragraphs for readability
Arrays
Categories:
- Provide full category hierarchy: ["Women", "Clothing", "Dresses", "Casual Dresses"]
- Use 1-100 items, each up to 200 characters
- Consistent naming improves faceted search
Tags:
- Always use tagType:value format: "color:Red" not "Red"
- Use consistent tag types: color, size, material, style, occasion
- Supports 1-2000 tags, each up to 1000 characters
- More tags = better discoverability
Media:
- Provide images for all variations
- Use variationId to link images to color/style variants
- Include descriptive altText for accessibility (up to 500 chars)
- High-res URLs improve image search capabilities
Features: - Use for bullet points and key highlights - Each feature can be up to 2000 characters - Include specifications, materials, dimensions, care instructions
Variations & SKUs
Linking Variations:
- Define variations with unique IDs: {id: "red", name: "Red"}
- Link SKUs to variations: {variationId: "red", size: "Small"}
- Link media to variations: {url: "...", variationId: "red"}
- Ensures proper filtering and display
SKU Management:
- Keep availability status current
- Update inventoryQuantity regularly
- Use promoPrice for sale pricing
- Include size information when applicable
Performance
- Request Size: Keep individual requests under 1MB for optimal performance
- Bulk Updates: Use multiple API calls rather than one massive payload
- Timing: Consider batching updates during low-traffic periods
- Rate Limiting: Respect API rate limits (contact Velou if you need higher limits)
Error Handling For Product Indexing
- Retry Logic: Implement exponential backoff for failed requests
- Validation: Pre-validate data before sending to reduce errors
- Logging: Log all validation errors for analysis
- Monitoring: Track task completion via the Task Tracking endpoint
Quick Reference Card
Required Fields
id(1-200 chars)url(1-2000 chars, URI format)skus[](1-300 items)skus[].price(number >= 0)skus[].variationId(required, 1–200 characters)
Common Field Limits
- URLs: 2000 characters (product, media, variations)
- Product Name: 500 characters
- All IDs: 200 characters
- Description: 10,000 characters
- Brand: 200 characters
- Slug: 300 characters
- Categories/Collections: 200 characters each
- Alt Text: 500 characters
Enum Fields
- gender:
Men|Women|Unisex - ageGroup:
Adults|Teens|Kids - availability:
InStock|OutOfStock|PreOrder|LimitedAvailability| etc. - popularity.type:
STAR|LIKES|THUMBS
Array Limits
- skus: 1-300 items (required)
- media: 1-150 items
- variations: 1-50 items (required)
- tags: 1-2000 items
- customUserTags: 1-200 items
- categories: 1-100 items
- collections: 1-100 items
- features: 1-50 items
Special Formats
- Tags: Must use
tagType:valueformat (e.g.,"color:Red") - URLs: Must be valid URI format
- Numbers: Must be >= 0 for prices, ratings, counts
- customUserData keys:
^[a-zA-z][a-zA-Z0-9]{0,30}$
Delete Product
This API prodivdes facility to delete an existing product from Velou index. It is important that you leverage this API to keep the Velou product index up-to-date at all times. Consider invoking this API whenever a product is removed from your product catalog. Please note that this API call is asynchronous. Once the API is invoked, you will receive an unique task identifier which you can use to track the status of the task.
Sample Request
curl -X DELETE 'https://{API_HOST}/1.0/products/1636730011711' \
-H 'X-Velou-API-Key: <api-key-admin>'
Sample Response
{
"taskId": "4fe09ba9f54e81f98e18bce903521981e71fad48"
}
Request
DELETE /products/{id}
Required API Key: admin
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
| id (URL) | String | Unique product identifier | NULL | 1636730011711 |
Response
| Parameter | Type | Description |
|---|---|---|
| taskId | String | Unique task identifier |
Task Tracking
All asynchronous API calls supported by Velou during the product indexing returns a unique task identifier. Task tracking API is useful to understand the current status of each task you've queued on Velou indexing process. This API takes a unique task identifier as the input.
Sample Request
curl -X GET 'https://{API_HOST}/1.0/tasks/4fe09ba9f54e81f98e18bce903521981e71fad48' \
-H 'X-Velou-API-Key: <api-key-admin>'
Sample Response
{
"status": "complete",
"createdAt": "2018-12-30 16:21:00.480Z",
"updatedAt": "2018-12-30 16:22:00.480Z"
}
Task Tracking Request
GET /tasks/{id}
Required API Key: admin
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
| id | String | Unique task identifier | NULL | 4fe09ba9f54e81f98e18bce903521981e71fad48 |
Task Tracking Response
| Parameter | Type | Description |
|---|---|---|
| status | Enum ["pending", "complete", "error"] | Current status of the task |
| createdAt | Date | Timestamp at which task was created |
| updatedAt | Date | Timestamp at which task was last updated |
Searching
Search Results
Velou provides an API for searching the catalog of products indexed in your Velou account. The API provides the ability to return results based on a search query. The response will include data points to build a powerful search experience, such as products that match the search criteria, available facet options to further refine the results, spell correction suggestions and data useful for paginating the search results.
Sample Request
curl -X GET 'https://{API_HOST}/1.0/search?query=red%20long%20sleeve%20dress&offset=100&pageSize=50&spellEnabled=true&facetsEnabled=true&facets=color:red,sleeve_length:long&userId=51w0orqu5&sessionId=bd0fl9aoc'
Sample Response
{
"totalProductCount": 1,
"products": [
{
"id": "605a14affb1e95bd9cb37fba",
"productId": "6158888960197",
"url": "https://demo.velou.com/products/texas-rose-plus",
"name": "Texas Rose - Plus",
"designer": "Bali ELF",
"price": {
"min": 139.95,
"max": 139.95
},
"promoPrice": {
"min": 0,
"max": 0
},
"initialPrice": {
"min": 186.95,
"max": 186.95
},
"customProps": {},
"defaultColorId": "2",
"colors": {
"1": {
"name": "White",
"swatch": "https://demo-images.velou.com/w_150/f_auto/q_auto/ar_0.66,c_fill/v1604012081/product-images-octo/labo5b0btg7sxlfpxavd.jpg",
"images": [
{
"s": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604012081/product-images-octo/labo5b0btg7sxlfpxavd.jpg",
"m": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604012081/product-images-octo/labo5b0btg7sxlfpxavd.jpg",
"l": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604012081/product-images-octo/labo5b0btg7sxlfpxavd.jpg"
}
],
"values": [
{
"hex": "e0d3c3",
"ratio": 50
},
{
"hex": "d1c2a8",
"ratio": 50
}
],
"productUrl": "https://demo.velou.com/products/texas-rose-plus?variant=37897423225029",
"promoPrice": {
"min": 0,
"max": 0
},
"price": {
"min": 139.95,
"max": 139.95
},
"initialPrice": {
"min": 186.95,
"max": 186.95
}
},
"2": {
"name": "Ruby",
"swatch": "https://demo-images.velou.com/w_150/f_auto/q_auto/ar_0.66,c_fill/v1604009390/product-images-octo/zfe71m3npqzc3jl5yxl5.jpg",
"images": [
{
"s": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604009390/product-images-octo/zfe71m3npqzc3jl5yxl5.jpg",
"m": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604009390/product-images-octo/zfe71m3npqzc3jl5yxl5.jpg",
"l": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604009390/product-images-octo/zfe71m3npqzc3jl5yxl5.jpg"
}
],
"values": [
{
"hex": "4b0d1d",
"ratio": 12
},
{
"hex": "791e37",
"ratio": 43
},
{
"hex": "91354e",
"ratio": 45
}
],
"productUrl": "https://demo.velou.com/products/texas-rose-plus?variant=37897423257797",
"promoPrice": {
"min": 0,
"max": 0
},
"price": {
"min": 139.95,
"max": 139.95
},
"initialPrice": {
"min": 186.95,
"max": 186.95
}
},
"3": {
"name": "Navy Blue",
"swatch": "https://demo-images.velou.com/w_150/f_auto/q_auto/ar_0.66,c_fill/v1604010964/product-images-octo/g4xdj4mmwksgzmezjjkw.jpg",
"images": [
{
"s": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604010964/product-images-octo/g4xdj4mmwksgzmezjjkw.jpg",
"m": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604010964/product-images-octo/g4xdj4mmwksgzmezjjkw.jpg",
"l": "https://demo-images.velou.com/w_750/f_auto/q_auto/ar_0.66,c_fill/v1604010964/product-images-octo/g4xdj4mmwksgzmezjjkw.jpg"
}
],
"values": [
{
"hex": "0d1e36",
"ratio": 30
},
{
"hex": "36597c",
"ratio": 17
},
{
"hex": "8e969d",
"ratio": 53
}
],
"productUrl": "https://demo.velou.com/products/texas-rose-plus?variant=37897423290565",
"promoPrice": {
"min": 0,
"max": 0
},
"price": {
"min": 139.95,
"max": 139.95
},
"initialPrice": {
"min": 186.95,
"max": 186.95
}
}
}
}
],
"facets": [
{
"key": "price",
"name": "Price",
"values": [
{
"key": "r10",
"count": 1,
"lb": 80,
"ub": 100
},
{
"key": "r11",
"count": 1,
"lb": 100,
"ub": 120
},
{
"key": "r12",
"count": 2,
"lb": 120,
"ub": 140
}
]
},
{
"key": "fit",
"name": "Fit",
"values": [
{
"key": "plus",
"name": "Plus",
"count": 2
}
]
}
],
"spellSuggestions": [],
"query": "red long sleeve dress",
"collection": "new-arrivals"
}
Search Request
GET /search
Required API Key: search
| Parameter | Type | Description |
|---|---|---|
| query | String | Search term used for filtering. At least one of query or collection parameters must be supplied. Example: red long sleeve dress. |
| collection | String | Collection handle used for filtering. At least one of query or collection parameters must be supplied. Example: dresses |
| from | Number | Pagination offset Example: 100 |
| pageSize | Number | Number of records per page Example: 50 |
| userId | String | Unique identifier for current shopper. This information is used to identify returning shoppers for personalization Example: 51w0orqu5 |
| sessionId | String | Unique identifier for current session. This information is used for personalization Example: bd0fl9aoc |
| preprod | Boolean | Set true to indicate that we are running on the pre production mode. In the pre production mode, Velou receives search queries when the shoppers perform searches. But they still see the results from the website's existing search solution. Pre-production mode is usually used to examin production traffic just before deploying Velou search on production Example: true |
| returnFacets | Boolean | Set true to return facets Example: true |
| facets | String | Current selected facets as key-value pairs separated by commas Example: color:red,sleeve_length:long |
| campaignProducts | String | Comma separated value of product ids. Used with campaign value in sortBy Example: 261252712,373849939,473673552 |
| sortBy | String | Sort parameter. Following values are supported at the moment.
Example: rating |
Search Response
| Parameter | Type | Description |
|---|---|---|
| totalProductCount | Number | Total search results count |
| products | Array[Product] | Paginated list of search results |
| fallback | Boolean | Indicates if the search engine decided to run a fallback query instead of the query sent through the query parameter. This might happen if the original query is not producing any results. This flag can be used to display a message to the shopper indicating produced results are not for his original query |
| facets | Array[Facet] | Dynamic list of facet options to narrow down current search results |
| spellSuggestions | Array[String] | List of spell suggestions for current search term |
| query | String | Search term used for filtering if available |
| collection | String | Collection handle used for filtering if available |
Search Response: Product Object
| Parameter | Type | Description |
|---|---|---|
| id | String | Unique Velou product identifier |
| productId | String | Unique store product identifier |
| url | String | URL of original product detail page |
| name | String | Name of the product |
| designer | String | Brand name of the manufacturer |
| price | Object | Price range considering all SKUs
|
| promoPrice | Object | Promotional price range considering all SKUs
|
| initialPrice | Object | Initial price range considering all SKUs
|
| customUserData | Object | Custom data passed to frontend for customer specific actions like showing various badges on the products, setting customer specific ids
|
| productPopularity | Object | Product ratings data. Please refer to popularity in index API for more information |
| defaultColorId | String | Id of the color variant that should be selected by default |
| colors | Object | List of color variations
|
| ccv | Object | Converted price values for the product if the currency conversion is configured for this store Object |
Search Response: Color Variation Object
| Parameter | Type | Description |
|---|---|---|
| name | String | Name of the variation (Color) |
| swatch | String | URL of the swatch image if available |
| images | Object | List of images
|
| values | Array[Color] | Color composition of the variation if the color details are extracted |
| productName | String | Name of the color variant. Some e-commerce stores have slightly different product names for the color variations |
| productUrl | String | URL of original product detail page for this color variation |
| productId | String | Unique store product identifier for this color variation |
| promoPrice | Object | Promotional price range of the color variant considering all SKUs
|
| price | Object | Price range of the color variant considering all SKUs
|
| initialPrice | Object | Initial price range of the color variant considering all SKUs
|
| ccv | Object | Converted price values for the color variance if the currency conversion is configured for this store Object |
Search Response: Currency Conversion Object
| Parameter | Type | Description |
|---|---|---|
| price | Object | Converted price range of the product considering all SKUs
|
| promoPrice | Object | Converted promotional price range of the product considering all SKUs
|
| initialPrice | Object | Converted initial price range of the product considering all SKUs
|
| currency | String | Currency code of the converted currency |
Search Response: Facet Object
| Parameter | Type | Description |
|---|---|---|
| key | String | Unique key to identify the facet |
| name | String | Name of the facet |
| values | Array[FacetValue] | List of facet values for current facet |
Search Response: Facet Value Object
| Parameter | Type | Description |
|---|---|---|
| key | String | Unique key to identify the facet value |
| name | String | Name of the facet value |
| count | Number | Number of search results for facet value |
Search Response: Color Value Object
| Parameter | Type | Description |
|---|---|---|
| hex | String | Hexadecimal value of the color |
| ratio | Number | Composition ratio of the color |
Query Suggestions
Velou provides an API to return helpful query recommendations based on shopper's current search query. This API can be handy to implement an autocomplete/typeahead feature as shopper inputs a partial search query. Velou's search algorithm generates query suggestions based on your indexed products catalog as well as using previous/popular search queries.
Sample Request
curl -X GET 'https://{API_HOST}/1.0/suggestions?query=bl' \
-H 'X-Velou-API-Key: <api-key-search>'
Sample Response
{
"query": "bl",
"suggestions": [
{
"id": 1,
"label": "Black",
"count": 86
},
{
"id": 2,
"label": "Black Clothing",
"count": 75
},
{
"id": 3,
"label": "Blouse",
"count": 40
}
]
}
Suggestions Request
GET /suggestions
Required API Key: search
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
| query | String | Search term | NULL | bl |
| preprod | Boolean | Set true to indicate that we are running on the pre production mode. In the pre production mode, Velou receives search queries when the shoppers perform searches. But they still see the results from the website's existing search solution. Pre-production mode is usually used to examin production traffic just before deploying Velou search on production | false | true |
Suggestions Response
| Parameter | Type | Description |
|---|---|---|
| suggestions | Array[Suggestion] | List of query suggestions matching search term |
| designers | Array[Suggestion] | List of brand suggestions matching search term |
| query | String | Search term |
Suggestions Response: Suggestion Object
| Parameter | Type | Description |
|---|---|---|
| id | String | Search term id |
| label | String | Suggested search term |
| count | Number | Number of search results for suggested search term |
Similarity
Velou provides you an API to find similar products for any given product. This facility can be used to show other similar products in a product description page for your shoppers further increasing the chance of them buying a product.
Sample Request
curl --request GET \
--url 'https://{API_HOST}/1.0/similarity?from=0&pageSize=20&productId=73529573021&variantId=12532'
Sample Response
{
"totalProductCount": 20,
"products": [
{
"product": {
"id": "615498f5d3c391de972a22bd",
"productId": "62853527846",
"url": "https://demo.velou.com/products/chiffon-wrap-top",
"name": "Navy Ruched Chiffon Wrap Top",
"designer": "ELF",
"price": {
"min": 9.99,
"max": 9.99,
"first": 9.99
},
"promoPrice": {
"min": 0,
"max": 0,
"first": 0
},
"initialPrice": {
"min": 24.99,
"max": 24.99,
"first": 24.99
},
"customUserData": {
"auroraId1": [
"286504"
]
},
"defaultColorId": "1",
"colors": {
"1": {
"name": "Navy",
"swatch": "https://demo.velou.com/images/navy",
"images": [
{
"s": "https://demo.velou.com/images/62853527846_s",
"m": "https://demo.velou.com/images/62853527846_m",
"l": "https://demo.velou.com/images/62853527846_l"
}
],
"promoPrice": {
"min": 0,
"max": 0
},
"price": {
"min": 9.99,
"max": 9.99,
"first": 9.99
},
"initialPrice": {
"min": 24.99,
"max": 24.99,
"first": 24.99
}
}
}
}
},
...
],
"facets": [
{
"key": "sizes",
"name": "Size",
"values": [
{
"key": "6",
"name": "6",
"count": 6
},
{
"key": "8",
"name": "8",
"count": 9
},
{
"key": "10",
"name": "10",
"count": 9
},
{
"key": "12",
"name": "12",
"count": 10
},
{
"key": "14",
"name": "14",
"count": 6
},
{
"key": "16",
"name": "16",
"count": 5
},
{
"key": "18",
"name": "18",
"count": 1
},
{
"key": "s",
"name": "S",
"count": 6
},
{
"key": "m",
"name": "M",
"count": 6
},
{
"key": "l",
"name": "L",
"count": 5
}
],
"specialValues": []
}
],
"sourceProduct": {
"productId": "73529573021",
"image": "https://demo.velou.com/images/00100029021_XM?$plptest$&fmt=webp",
"name": "Blue Knitted Wrap Jumper"
}
}
Similarity Request
GET /similarity
Required API Key: search
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
| productId | String | Velou search engine will find the similar products for the product that has this id | NULL | 628373838 |
| from | Number | Pagination offset | 0 | 100 |
| pageSize | Number | Number of records per page | 30 | 50 |
| variantId | String | Variant id. When searching similar products, this variant will also be considered if available | NULL | 62524 |
| facets | String | Current selected facets as key-value pairs separated by commas | NULL | sizes:10,sleeve_length:long |
Similarity Response
| Parameter | Type | Description |
|---|---|---|
| totalProductCount | Number | Total similar items count |
| products | Array[ProductWrapper] | Paginated list of similar items |
| facets | Array[Facet] | Dynamic list of facet options to narrow down similar items list |
| sourceProduct | Object | Details about the product similar items are returned for.
|
Response: ProductWrapper Object
| Parameter | Type | Description |
|---|---|---|
| product | Array[Product] | Product Object |
Complete The Look
The Complete the Look API enables customers to discover complementary products for a specific item, enhancing the shopping experience. By providing a curated set of products based on a given product ID, the API allows retailers to offer tailored outfit recommendations, encouraging shoppers to visualize and purchase a complete look.
Sample request
curl 'https://demo.velou.com/ctl?productId=DBGS123N'
Sample response
{
"ctlProducts": [
[
{
"id": "615498f5d3c391de972a22bd",
"productId": "DBGS123N",
"url": "https://demo.velou.com/62853527846/pull-over-hoodie-DBGS123N",
"name": "Pull Over Hoodie",
"designer": "Brand",
"price": {
"min": 19.99,
"max": 19.99,
"first": 19.99
},
"promoPrice": {
"min": 0,
"max": 0,
"first": 0
},
"initialPrice": {
"min": 39.99,
"max": 39.99,
"first": 39.99
},
"customUserData": {
"bannerInformation1": [
"none",
"n",
"80",
"Yes"
],
"dropShipProduct1": [
"NO"
],
"promotion1": [
"No"
],
"auroraId1": [
"12345"
]
},
"defaultColorId": "1",
"colors": {
"1": {
"name": "Red",
"swatch": "https://www.example.com/swatch-red.jpg",
"images": [
{
"s": "https://www.example.com/image-small-red.jpg",
"m": "https://www.example.com/image-medium-red.jpg",
"l": "https://www.example.com/image-large-red.jpg"
}
],
"values": [],
"productName": "",
"promoPrice": {
"min": 0,
"max": 0
},
"price": {
"min": 19.99,
"max": 19.99,
"first": 19.99
},
"initialPrice": {
"min": 39.99,
"max": 39.99,
"first": 39.99
}
}
},
"gender": "Unisex"
},
{
"id": "615498f5d3c391de972a22bc",
------
},
{
"id": "615498f5d3c391de972a22br",
------
},
{
"id": "615498f5d3c391de972a22bj",
------
}
]
]
}
Complete The Look Request
GET /ctl
| Parameter | Type | Description | Example |
|---|---|---|---|
| productId | String | The product ID is used to retrieve the CTL product set | DBGS123N |
Complete The Look Response
| Parameter | Type | Description |
|---|---|---|
| ctlProducts | Array [Array[Product]] | A list of product sets that is curated for complete the look |
Analytics
Event Tracking
Velou uses event tracking on your store to generate valuable insights on your shopper behavior and to monitor how Velou contributes to the convertion of your customers. Velou also uses these data points to boost the most important products to the top of search results based on past shopper behavior (ranking). It is highly recommend you report all event types accurately to get the maximum benefit through Velou's reporting platform and ranking algorithm.
Sample Request
curl -X POST 'https://{API_HOST}/1.0/tracking' \
-H 'Content-Type: application/json' \
-d '
{
"type": "Search",
"data": {,
"query": "Red Shirt",
"pageSize": 30,
"sortBy": "relevance",
"productIds": [
"6153342714048",
"6642820382912",
"6536276934848"
],
"facets": [
{
"key": "pattern",
"value": "floral"
}
],
"totalProducts": 3
},
"sessionId": "it2qa7ksj",
"userId": "bi34ly82v"
"storeId": "storeId"
}'
Sample Response
{
"ok":true
}
Request
POST /tracking
Required API Key: analytics
| Parameter | Type | Description |
|---|---|---|
| type | Enum ["SiteView", "Search", "PageChange", "SortByChange", "ProductClick","PromotionClick", "AddToCart", "OrderComplete", "Purchase", "ViewSimilarProducts", "SimilarProductClick", "CTLLoad", "CTLViewLookClick", "CTLProductClick", "CTLPopupProductClick", "CTLPageChange", "CTLPopupPageChange"] | Type of activity performed by the shopper |
| data | Object | Additional important details related to the event. Depending on the type, the values contained in data will be different: type = SiteView:
|
| userId | String | Randomly generated, anonymous string using base-36 encoding, designed for user tracking without storing any Personally Identifiable Information (PII) |
| sessionId | String | Randomly generated, anonymous string using base-36 encoding, designed for session tracking without storing any Personally Identifiable Information (PII) |
| storeId | String | Unique identifier of the shop |
Request: Purchased Product Object
| Parameter | Type | Description |
|---|---|---|
| id | String | Unique product identifier |
| price | Number | Price of the product |
| qty | Number | Quantity of the product |
Response
| Parameter | Type | Description |
|---|---|---|
| result | Enum ["success", "error"] | Result of the request |
Error Handling
Whether a request succeeded is indicated by the HTTP status code. A 2xx status code indicates success, whereas a 4xx status code indicates failure.
When a request fails, the response body is still JSON, but always contains a message field with a description of the error, which you can inspect for debugging.
The Velou API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request – Your request is invalid. Response body usually provides details of the error. |
| 401 | Unauthorized – Your Store ID or API Key is wrong. Ensure you are using API Key with required permissions to access the resource. |
| 404 | Not Found – Your request is looking for a non-existant resource. |
| 500 | Internal Server Error – An unexpected error occured at server-side. Retry the request after few minutes or contact Velou if problem persists over a long period. |
Content Generation Webhook
In addition to the search functionality, Velou can enrich your data by providing you product features identified by Velou. You can use webhook subscriptions to receive this information. Once subscribed, content generation webhooks will be called as soon as Velou identify the features of any product you send via the indexing API. It is possible to call the webhooks multiple times for a single product as Velou identify features at various stages of the analysis process. (E.g. Text analysis, Image analysis, etc)
Webhook Headers
| Header | Description | Example |
|---|---|---|
| x-velou-topic | Webhook Topic | tags |
| x-velou-hmac-sha256 | base64 encoded string that is used to verify a webhook notification | BE90+RWqMIFylcyc969HlGznlZ9MPnGQxvmEs+o5C7U= |
| x-velou-store-id | Id of the store registered with Velou | my_store_123 |
| x-velou-ts | UNIX timestamp in milliseconds. This is used to compute the HMAC hash for request authentication | 1638164106697 |
| x-velou-api-version | Version of the webhook API being used. | 1.3 |
| x-velou-webhook-id | Id of the webhook | 526143728 |
Webhook Body
| Parameter | Type | Description | Default |
|---|---|---|---|
| id | String | Unique Velou product identifier | |
| productId | String | Unique store product identifier | |
| category | String | Category of the product | |
| attributes | Object | Object containing key product attributes and their associated values
|
|
| productVersion | Number | Version number of the product, indicating updates or changes to the product data | |
| generatedContent | Array | Array containing generated contents using AI(i.e. Title, Description etc.)
|
Example webhook body given below
{
"id": "5f637c246b9eeecb1134a212",
"productId": "812456103",
"category": "dresses",
"attributes": {
"gender": {
"displayName": {
"en-gb": "Gender",
"fr-fr": "Genre"
},
"attributesValues": [
{
"women": {
"displayName": {
"en-gb": "Women",
"fr-fr": "Femmes"
},
"synonyms": [
{
"ladies": {
"displayName": {
"en-gb": "Ladies",
"fr-fr": "Dames"
}
}
}
],
"trending": true
}
}
]
},
"color": {
"displayName": {
"en-gb": "Color",
"fr-fr": "Couleur"
},
"attributesValues": [
{
"black": {
"displayName": {
"en-gb": "Black",
"fr-fr": "Noir"
},
"synonyms": []
}
}
]
},
"pattern": {
"displayName": {
"en-gb": "Pattern",
"fr-fr": "Motif"
},
"attributesValues": [
{
"solid": {
"displayName": {
"en-gb": "Solid",
"fr-fr": "Uni"
},
"synonyms": [
{
"plain": {
"displayName": {
"en-gb": "Plain",
"fr-fr": "Simple"
}
}
},
{
"without_pattern": {
"displayName": {
"en-gb": "Without pattern",
"fr-fr": "Sans motif"
}
}
}
]
}
}
]
}
},
"productVersion": 34,
"generatedContent": [
{
"fieldName": "productDescription",
"values": {
"en-gb": "This elegant black bodycon dress is perfect for evening events and special occasions. Featuring a solid pattern and a flattering fit, the dress includes a mini length, plunging neckline, ruching details, and long sleeves. Designed with a tulip hemline, this piece combines sophistication with style.",
"fr-fr": "Cette élégante robe moulante noire est parfaite pour les événements du soir et les occasions spéciales. Avec un motif uni et une coupe flatteuse, la robe comprend une longueur mini, un décolleté plongeant, des détails froncés et des manches longues. Conçue avec un ourlet en forme de tulipe, cette pièce combine sophistication et style."
}
},
{
"fieldName": "productTitle",
"values": {
"en-gb": "Women's Solid Black Bodycon Dress",
"fr-fr": "Robe moulante noire unie pour femme"
}
}
]
}
Retry Logic
If the webhook is not responded within 5 seconds or any status code other than 2xx is received, Velou consider it as a failure and fall back to a retry cycle. Following retry strategy is currently in place
- Try 3 times with 30 second interval in between
- Try 3 times with 2 minutes wait time between each attempt
- Try 3 times with 5 minutes wait time between each attempt
- Try 3 times with 1 hour wait time between each attempt
- Try 2 times with 6 hour wait time between each attempt
- Try one last time after 24 hours
Webhook Authentication
When you receive a webhook request, it is very important to verify that the request has originated from Velou before processing it any further. Velou provides a digital signature for you to use in this verification process. A string is generated by concatenating body of the request with number of other parameters. Final signature is obtained by signing this string with a shared secret key. Velou provides you this secret key as part of the setup process. A simple nodejs snippet is given below in order to explain the authentication process.
const express = require('express')
const crypto = require('crypto')
const getRawBody = require('raw-body')
const app = express()
const webhookSecret = MY_VELOU_SECRET
app.post('/webhook', async (req, res) => {
try {
// Parse the request body
const body = await getRawBody(req)
// Extract x-velou-hmac-sha256 header from the request
const hmacHash = req.header('x-velou-hmac-sha256')
// Extract x-velou-store-id header from the request
const storeId = req.header('x-velou-store-id')
// Extract x-velou-ts header from the request.
// This is a UNIX timestamp in milliseconds indicating the request created time.
const signatureTs = req.header('x-velou-ts')
// Extract x-velou-topic header from the request
// This is the webhooks topic. For tag generation, its value is "tags"
const topic = req.header('x-velou-topic')
// Extract x-velou-webhook-id header from the request
// When a webhook is registered with velou, its given a unique id
const id = req.header('x-velou-webhook-id')
const signatureSourceComponents = [
storeId, signatureTs, topic, id, body.toString('utf8')
]
const computedHash = crypto.createHmac('sha256', webhookSecret)
.update(signatureSourceComponents.join('.'))
.digest('base64')
if (computedHash === hmacHash) {
console.log("Webhook source confirmed. Continue processing");
res.sendStatus(200)
} else {
console.log("Unidentified webhook source. Do not process");
res.sendStatus(403)
}
} catch (e) {
console.error(e)
res.sendStatus(500)
}
})
app.listen(43215)
Best Practices
- The logic on the endpoint implementation must be bug free
- When you successfully process a webhook request, return one of 2xx rage of status codes. If there is a failure, return one of 4xx or 5xx range of status codes
- Respond to a webhook as fast as possible. Timeout is 5 seconds. After waiting for 5 seconds for your system to respond to a webhook request and still there is no response, Velou consider your system failed to handle the webhook request and act accordingly
- Your system must be able to handle the concurrent webhook requests. Concurrency level can vary based on various dynamic parameters but normally kept under 10
- Always use https for webhooks. Velou will not accept http endpoints for webhooks.
- Always verify your incoming webhooks to make sure that the webhook request is sent by Velou. Refer to authentication for more details
- Idempotency in webhook processing. Velou might call your webhook multiple times for the same product. Your processing logic must be able to handle such situations without any negative impact on your system
JavaScript Integration
To integrate the Velou functions from the front end, Velou will provide a customized JavaScript implementation that needs to be embedded in the HTML header of the application as shown in the example. Velou will manage the search look-and-feel of the functions as agreed with both parties.
<html>
<head>
<script src="https://{VELOU_JS_HOST}/velou.min.js"></script>
</head>
</html>
Search Integration
A route/page as shown in the example will include the relevant headers and footers. The page should also include a div with a unique id (i.e. velou-search-results) to embed the search results.
https://{YOUR_DOMAIN}/search-results