> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

# SearchVariants

# Package: catalogV3

# Namespace: ProductVariantsReader

# Method link: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/read-only-variants-v3/search-variants.md

## Permission Scopes:
Read products in v3 catalog: SCOPE.STORES.PRODUCT_READ
Product v3 read admin: SCOPE.STORES.PRODUCT_READ_ADMIN

## Introduction

Search product variants using free-text search with advanced query capabilities.

Use this endpoint for complex queries that include free-text search, aggregations,
or when you need faceted search results. For simple filtering, use Query Variants instead.

To learn about working with _Search_ methods, see
[API Query Language](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-the-wix-api-query-language.md)
and [Sorting and Paging](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-sorting-and-paging.md).

Learn more about the differences between [_Query_ and _Search_](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-search-query-and-list-methods.md) methods.

When `search.sort` is empty (first request of a cursor search), results are ordered by
`productData.updatedDate` (descending), then `productData.productId` (ascending), then `variantId` (ascending).

> **Note:** Non-visible variants, and variants related to non-visible products are filtered from results if you don't have permissions to read hidden products.

---

## REST API

### Schema

```
 Method: searchVariants
 Description: Search product variants using free-text search with advanced query capabilities.  Use this endpoint for complex queries that include free-text search, aggregations, or when you need faceted search results. For simple filtering, use Query Variants instead.  To learn about working with _Search_ methods, see [API Query Language](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-the-wix-api-query-language.md) and [Sorting and Paging](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-sorting-and-paging.md).  Learn more about the differences between [_Query_ and _Search_](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-search-query-and-list-methods.md) methods.  When `search.sort` is empty (first request of a cursor search), results are ordered by `productData.updatedDate` (descending), then `productData.productId` (ascending), then `variantId` (ascending).  > **Note:** Non-visible variants, and variants related to non-visible products are filtered from results if you don't have permissions to read hidden products.
 URL: https://www.wixapis.com/stores/v3/products/search-variants
 Method: POST
 Method parameters:
   param name: fields | type: array<fields> | description: List of additional fields to include in the response. See VariantOps.RequestedFields for available options.  | validation: maxItems 100
                 - enum:
                 -     CURRENCY: Include currency information in product data.  Returns the currency code (ISO-4217 format) used for pricing this variant. Defaults to the site's currency unless specified in request headers.
                 -     MERCHANT_DATA: Include merchant-specific data such as cost and profit information.  Returns revenue details including cost, profit, and profit margin. Requires `SCOPE.STORES.PRODUCT_READ_ADMIN` permission scope.
                 -     SUBSCRIPTION_PRICES_INFO: Include subscription pricing information.  Returns calculated prices for different subscription plans with applied discounts. Only relevant for variants that are part of subscription offerings.
                 -     WEIGHT_MEASUREMENT_UNIT_INFO: Include weight measurement unit information.  Returns the weight measurement unit (kg, lb, etc.) used for the variant. Useful for shipping calculations and product comparisons.
   param name: search | type: CursorSearch    
     - name: cursorPaging | type: CursorPaging | description: Cursor pointing to page of results. When requesting 'cursor_paging.cursor', no `filter`, `sort` or `search` can be provided.  
        - name: limit | type: integer | description: Maximum number of items to return in the results.  | validation: minimum 0, maximum 1000, format int32
        - name: cursor | type: string | description: Pointer to the next or previous page in the list of results.  Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response. Not relevant for the first request.  | validation: maxLength 16000
        - name: filter | type: object | description: A filter object. See documentation [here](https://bo.wix.com/wix-docs/rnd/platformization-guidelines/api-query-language#platformization-guidelines_api-query-language_defining-in-protobuf)  
        - name: sort | type: array<Sorting> | description: Sort object in the form [{"fieldName":"sortField1"},{"fieldName":"sortField2","direction":"DESC"}]  | validation: maxItems 10
           - name: fieldName | type: string | description: Name of the field to sort by.  | validation: maxLength 512
           - name: order | type: SortOrder | description: Sort order.  
                 - enum: ASC, DESC
        - name: aggregations | type: array<Aggregation> | description: Aggregations | Faceted search: refers to a way to explore large amounts of data by displaying summaries about various partitions of the data and later allowing to narrow the navigation to a specific partition.  | validation: maxItems 10
           - ONE-OF: 
              - name: value | type: ValueAggregation | description: Value aggregation  
                 - ONE-OF: 
                    - name: includeOptions | type: IncludeMissingValuesOptions | description: Options for including missing values  
                       - name: addToBucket | type: string | description: Can specify custom bucket name. Defaults are [string -> "N/A"], [int -> "0"], [bool -> "false"] ...  | validation: maxLength 20
                 - name: sortType | type: SortType | description: Should sort by number of matches or value of the field  
                         - enum:
                         -     COUNT: Should sort by number of matches
                         -     VALUE: Should sort by value of the field alphabetically
                 - name: sortDirection | type: SortDirection | description: Should sort in ascending or descending order  
                         - enum:
                         -     DESC: Should sort in descending order
                         -     ASC: Should sort in ascending order
                 - name: limit | type: integer | description: How many aggregations would you like to return? Can be between 1 and 250. 10 is the default.  | validation: format int32
                 - name: missingValues | type: MissingValues | description: Should missing values be included or excluded from the aggregation results. Default is EXCLUDE  
                         - enum:
                         -     EXCLUDE: Should missing values be excluded from the aggregation results
                         -     INCLUDE: Should missing values be included in the aggregation results
              - name: range | type: RangeAggregation | description: Range aggregation  
                 - name: buckets | type: array<RangeBucket> | description: List of range buckets, where during aggregation each entity will be placed in the first bucket where its value falls into based on provided range bounds  | validation: maxItems 50
                    - name: from | type: number | description: Inclusive lower bound of the range. Required if to is not given  | validation: format double
                    - name: to | type: number | description: Exclusive upper bound of the range. Required if from is not given  | validation: format double
              - name: scalar | type: ScalarAggregation | description: Scalar aggregation  
                 - name: type | type: ScalarType | description: Define the operator for the scalar aggregation  
                         - enum:
                         -     COUNT_DISTINCT: Count of distinct values
                         -     MIN: Minimum value
                         -     MAX: Maximum value
              - name: dateHistogram | type: DateHistogramAggregation | description: Date histogram aggregation  
                 - name: interval | type: Interval | description: Interval for date histogram aggregation  
                         - enum:
                         -     YEAR: Yearly interval
                         -     MONTH: Monthly interval
                         -     WEEK: Weekly interval
                         -     DAY: Daily interval
                         -     HOUR: Hourly interval
                         -     MINUTE: Minute interval
                         -     SECOND: Second interval
              - name: nested | type: NestedAggregation | description: Nested aggregation  
                 - name: nestedAggregations | type: array<NestedAggregationItem> | description: Flattened list of aggregations, where each next aggregation is nested within previous one  | validation: minItems 2, maxItems 3
                    - ONE-OF: 
                       - name: value | type: ValueAggregation | description: Value aggregation  
                       - name: range | type: RangeAggregation | description: Range aggregation  
                       - name: scalar | type: ScalarAggregation | description: Scalar aggregation  
                       - name: dateHistogram | type: DateHistogramAggregation | description: Date histogram aggregation  
                    - name: name | type: string | description: User-defined name of aggregation, should be unique, will appear in aggregation results  | validation: maxLength 100
                    - name: type | type: NestedAggregationType | description: Type of aggregation, client must provide matching aggregation field below  
                             - enum:
                             -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                             -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                             -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                             -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                    - name: fieldPath | type: string | description: Field to aggregate by, use dont notation to specify json path  | validation: maxLength 200
           - name: name | type: string | description: User-defined name of aggregation, should be unique, will appear in aggregation results  | validation: maxLength 100
           - name: type | type: AggregationType | description: Type of aggregation, client must provide matching aggregation field below  
                 - enum:
                 -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                 -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                 -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                 -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                 -     NESTED: Multi-level aggregation, where each next aggregation is nested within previous one
           - name: fieldPath | type: string | description: Field to aggregate by, use dot notation to specify json path  | validation: maxLength 200
        - name: search | type: SearchDetails | description: Free text to match in searchable fields  
           - name: mode | type: Mode | description: Defines how separate search terms in `expression` are combined  
                 - enum:
                 -     OR: Any of the search terms must be present
                 -     AND: All search terms must be present
           - name: expression | type: string | description: Search term or expression  | validation: maxLength 100
           - name: fields | type: array<string> | description: Fields to search in. If empty - will search in all searchable fields. Use dot notation to specify json path  | validation: maxItems 20, maxLength 200
           - name: fuzzy | type: boolean | description: Flag if should use auto fuzzy search (allowing typos by a managed proximity algorithm)  
        - name: timeZone | type: string | description: UTC offset or IANA time zone. Valid values are ISO 8601 UTC offsets, such as +02:00 or -06:00, and IANA time zone GUIDs, such as Europe/Rome  Affects all filters and aggregations returned values. You may override this behavior in a specific filter by providing timestamps including time zone. e.g. `"2023-12-20T10:52:34.795Z"`  | validation: maxLength 50
 Searchable fields:
   - field: id | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: none | aggregatable: true | searchable: false
   - field: optionChoices.optionChoiceIds.choiceId | operators: $hasAll, $hasSome | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: optionChoices.optionChoiceIds.optionId | operators: $hasAll, $hasSome | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: barcode | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: inventoryStatus.inStock | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: inventoryStatus.preorderEnabled | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: price.actualPrice.amount | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: price.compareAtPrice.amount | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.updatedDate | operators: $eq, $ne, $exists, $in, $any, $lt, $lte, $gt, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.brand.id | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.handle | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.name | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: true
   - field: productData.productId | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.productType | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.slug | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.visible | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.visibleInPos | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: sku | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: true
   - field: variantId | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: visible | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
 Return type: SearchVariantsResponse
  - name: variants | type: array<ReadOnlyVariant> | description: Variants matching the search criteria.  
     - ONE-OF: 
        - name: physicalProperties | type: VariantPhysicalProperties | description: Physical properties such as weight and dimensions.  Required when the product type is `PHYSICAL`.  
           - name: weight | type: number | description: Weight of the variant for shipping calculations.  Used for shipping cost calculations and fulfillment planning. Returned only when you pass `"WEIGHT_MEASUREMENT_UNIT_INFO"` to the `fields` parameter.  | validation: minimum 0, maximum 999999999.99, format double
           - name: pricePerUnit | type: PricePerUnit | description: Price per unit measurement information.  Allows customers to compare prices based on a standard unit (like price per kilogram or per liter). Useful for bulk products or items sold by weight or volume.  
              - name: settings | type: PricePerUnitSettings | description: Price per unit measurement settings.  Defines the unit of measurement for price comparison (e.g., per kilogram, per liter). The measurement unit must correspond to the unit set on the parent product.  
                 - name: quantity | type: number | description: Quantity. For example, to define price per per 100 grams, set this field to `100`.  | validation: minimum 0.01, maximum 999999999.99
                 - name: measurementUnit | type: MeasurementUnit | description: Measurement unit. For example, to define price per 100 grams, set this field to "G".  
                         - enum: UNSPECIFIED, ML, CL, L, CBM, MG, G, KG, MM, CM, M, SQM, OZ, LB, FLOZ, PT, QT, GAL, IN, FT, YD, SQFT
              - name: value | type: string | description: Calculated price per unit value.  Shows the variant's price normalized to the standard unit of measurement. For example, if a 500g variant costs $2 and the standard unit is 1kg, this value would be $4.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
              - name: description | type: string | description: Human-readable description of the price per unit.  For example, "per kg" or "per liter".  | validation: maxLength 100
        - name: digitalProperties | type: VariantDigitalProperties | description: Digital properties such as downloadable files.  Required when the product type is `DIGITAL`.  
           - name: digitalFile | type: SecuredMedia | description: Digital file available for download after purchase.  The file that customers receive when they purchase this digital variant.  
              - name: id | type: string | description: Media GUID in media manager.  | validation: minLength 1, maxLength 100
              - name: fileName | type: string | description: Original file name.  | validation: minLength 1, maxLength 1000
              - name: fileSize | type: string | description: Original file size.  | validation: minLength 1, maxLength 1000, format DECIMAL_VALUE, decimalValue {"maxScale":0}
              - name: fileType | type: FileType | description: File type.  
                     - enum:
                     -     UNSPECIFIED: Unspecified file type.
                     -     SECURE_PICTURE: Secure picture file.
                     -     SECURE_VIDEO: Secure video file.
                     -     SECURE_DOCUMENT: Secure document file.
                     -     SECURE_MUSIC: Secure music file.
                     -     SECURE_ARCHIVE: Secure archive file.
                     -     SECURE_RAW: Secure raw file.
     - name: visible | type: boolean | description: Whether the variant is visible to site visitors.  Default: `true`  
     - name: sku | type: string | description: Stock keeping unit (SKU) for inventory tracking and identification.  The SKU is typically used for inventory management, order fulfillment, and product identification across different systems.  | validation: minLength 1, maxLength 40
     - name: barcode | type: string | description: Barcode for the variant, typically used for point-of-sale systems and inventory management.  Common barcode formats include UPC, EAN, and Code 128. The barcode helps with quick product identification and checkout processes.  | validation: minLength 1, maxLength 40
     - name: optionChoices | type: array<OptionChoice> | description: Product option choices that define this variant.  Each option choice represents a specific selection for a product option (like "Size: Large" or "Color: Red"). An empty list indicates this is the default variant of a product with no managed options.  | validation: minItems 0, maxItems 6
        - name: optionChoiceIds | type: OptionChoiceIds | description: Option and choice identifiers.  
           - name: optionId | type: string | description: Product option GUID.  | validation: minLength 1, maxLength 36
           - name: choiceId | type: string | description: Specific choice GUID within the option.  | validation: format GUID
        - name: optionChoiceNames | type: OptionChoiceNames | description: Human-readable option and choice names.  
           - name: optionName | type: string | description: Display name of the product option.  For example, "Size", "Color", or "Material".  | validation: minLength 1, maxLength 50
           - name: choiceName | type: string | description: Display name of the chosen option value.  For example, "Large", "Red", or "Cotton".  | validation: minLength 1, maxLength 50
           - name: renderType | type: string | description: Visual representation style for the option choice.  Determines how the option is displayed in the product selector UI. Common values include "TEXT_CHOICES", "COLOR_CHOICES", or "IMAGE_CHOICES".  | validation: maxLength 50
     - name: price | type: PriceInfo | description: Pricing information for the variant.  
        - name: actualPrice | type: FixedMonetaryAmount | description: Current selling price of the variant.  
           - name: amount | type: string | description: Monetary amount. For example, `"3.99"`, or `"-4.99"` for a negative amount.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
           - name: formattedAmount | type: string | description: Formatted monetary amount. For example, `"$3.99"`. > **Note:** Returned only when you pass `"CURRENCY"` to the `fields` array in Read-Only Variants API requests.  | validation: maxLength 20
        - name: compareAtPrice | type: FixedMonetaryAmount | description: Original price before any discounts.  Used to show customers the savings when the variant is on sale. If not set, no original price is displayed.  
     - name: revenueDetails | type: RevenueDetails | description: Revenue and cost details for business analytics.  Includes cost, profit, and profit margin calculations. Returned only when you pass `"MERCHANT_DATA"` to the `fields` parameter.  
        - name: cost | type: FixedMonetaryAmount | description: Cost of the variant for profit calculations.  The amount you pay to produce or acquire this variant.  
        - name: profit | type: FixedMonetaryAmount | description: Profit amount calculated by subtracting cost from the discounted price.  
        - name: profitMargin | type: number | description: Profit margin as a percentage of the selling price.  Calculated by dividing profit by the discounted price. The result is rounded to 4 decimal places. A value of 0.25 represents a 25% profit margin.  | validation: minimum 0, maximum 1
     - name: media | type: ProductMedia | description: Media associated with the variant.  Typically includes images, videos, or other media files specific to this variant.  
        - name: altText | type: string | description: Image alt text.  | validation: minLength 1, maxLength 1000
        - name: displayName | type: string | description: Media display name. Allows to override the default media name. Can be passed only when `setBy: url`.  | validation: maxLength 80
        - name: mediaType | type: MediaType | description: Media type.  
             - enum:
             -     IMAGE: Image media type.
             -     VIDEO: Video media type.
        - name: thumbnail | type: Thumbnail | description: Media thumbnail.  
           - name: url | type: string | description: Thumbnail URL.  | validation: format WEB_URL
           - name: height | type: integer | description: Thumbnail height.  
           - name: width | type: integer | description: Thumbnail width.  
           - name: altText | type: string | description: Thumbnail alt text.  | validation: minLength 1, maxLength 1000
        - name: uploadId | type: string | description: GUID used to upload media to Wix Media Manager.  | validation: format GUID
     - name: subscriptionPricesInfo | type: SubscriptionPricesInfo | description: Subscription pricing information when the variant is part of subscription plans.  Shows calculated prices after applying subscription discounts to the variant's price. Returned only when you pass `"SUBSCRIPTION_PRICES_INFO"` to the `fields` parameter.  
        - name: subscriptionPrices | type: array<SubscriptionPrice> | description: Pricing for different subscription plans.  Shows how the variant's price changes with different subscription intervals or discounts.  | validation: maxItems 6
           - name: subscriptionId | type: string | description: Subscription plan GUID.  | validation: format GUID
           - name: price | type: FixedMonetaryAmount | description: Variant price with subscription discount applied.  
           - name: pricePerUnit | type: SubscriptionPricePerUnit | description: Price per unit for subscription pricing.  
              - name: value | type: string | description: Calculated price per unit for the subscription.  Takes into account the subscription discount and the variant's price per unit settings.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
              - name: description | type: string | description: Description of the subscription price per unit.  | validation: maxLength 20
     - name: inventoryStatus | type: InventoryStatus | description: Current inventory and availability status.  
        - name: inStock | type: boolean | description: Whether the variant is currently in stock and available for purchase.  
        - name: preorderEnabled | type: boolean | description: Whether customers can place preorders for this variant when it's out of stock.  
     - name: productData | type: ProductFields | description: Product information for context and convenience.  Includes essential product details like name, visibility, and categories to avoid requiring separate product API calls when working with variants.  
        - ONE-OF: 
           - name: physicalProperties | type: PhysicalProperties | description: Physical product properties such as weight and dimensions.  Required when `productType` is `PHYSICAL`.  
              - name: weightMeasurementUnitInfo | type: WeightMeasurementUnitInfo | description: Weight measurement unit information for the product.  Defines the unit of measurement (kg, lb, etc.) used for product weight calculations. Returned only when you pass `"WEIGHT_MEASUREMENT_UNIT_INFO"` to the `fields` parameter.  
                 - name: weightMeasurementUnit | type: WeightUnit | description: Unit of measurement for weight.  Standard units include kilograms (KG), pounds (LB), ounces (OZ), and grams (G).  
                         - enum:
                         -     UNSPECIFIED_WEIGHT_UNIT: Weight unit can't be classified due to an error.
                         -     KG: Kilograms.
                         -     LB: Pounds.
        - name: productId | type: string | description: Product GUID.  | validation: minLength 1, maxLength 36
        - name: name | type: string | description: Product name displayed to customers.  | validation: minLength 1, maxLength 80
        - name: productType | type: ProductType | description: Type of product determining available properties and behavior.  
             - enum:
             -     PHYSICAL: Physical product.
             -     DIGITAL: Digital product.
        - name: slug | type: string | description: URL-friendly identifier for the product.  Used in product page URLs and for SEO optimization.  | validation: format URL_SLUG
        - name: visible | type: boolean | description: Whether the product is visible to site visitors.  Default: `true`  
        - name: visibleInPos | type: boolean | description: Whether the product appears in point-of-sale systems.  Default: `true` Always `false` for digital products.  
        - name: mainCategoryId | type: string | description: Primary category assignment for the product.  Determines the main category used for navigation and organization.  | validation: format GUID
        - name: currency | type: string | description: Currency used for pricing this product.  Three-letter currency code in ISO-4217 alphabetic format. Defaults to the site's currency setting unless specified in request headers. Returned only when you pass `"CURRENCY"` to the `fields` parameter.  | validation: format CURRENCY
        - name: revision | type: string | description: Revision number, which increments by 1 each time the product is updated. To prevent conflicting changes, the current revision must be passed when updating the product.  | validation: format int64
        - name: handle | type: string | description: A unique human-friendly identifier for the product.  The handle can be set by the user to ensure consistency across multiple platforms.  | validation: minLength 1, maxLength 100
     - name: variantId | type: string | description: Variant GUID. Not guaranteed to be unique across products, so it should be used together with `productData.productId` as the unique variant key.  | validation: format GUID
  - name: pagingMetadata | type: CursorPagingMetadata | description: Pagination information with cursors for next pages.  
     - name: count | type: integer | description: Number of items returned in the response.  | validation: format int32
     - name: cursors | type: Cursors | description: Cursor strings that point to the next page, previous page, or both.  
        - name: next | type: string | description: Cursor string pointing to the next page in the list of results.  | validation: maxLength 16000
        - name: prev | type: string | description: Cursor pointing to the previous page in the list of results.  | validation: maxLength 16000
     - name: hasNext | type: boolean | description: Whether there are more pages to retrieve following the current page.  + `true`: Another page of results can be retrieved. + `false`: This is the last page.  
  - name: aggregationData | type: AggregationData | description: Aggregation results for faceted search.  
     - name: results | type: array<AggregationResults> | description: key = aggregation name (as derived from search request)  | validation: maxItems 10000
        - ONE-OF: 
           - name: values | type: ValueResults | description: Value aggregation results  
              - name: results | type: array<ValueAggregationResult> | description: List of value aggregations  | validation: maxItems 250
                 - name: value | type: string | description: Value of the field  | validation: maxLength 100
                 - name: count | type: integer | description: Count of entities with this value  
           - name: ranges | type: RangeResults | description: Range aggregation results  
              - name: results | type: array<RangeAggregationResult> | description: List of ranges returned in same order as requested  | validation: maxItems 50
                 - name: from | type: number | description: Inclusive lower bound of the range  | validation: format double
                 - name: to | type: number | description: Exclusive upper bound of the range  | validation: format double
                 - name: count | type: integer | description: Count of entities in this range  
           - name: scalar | type: ScalarResult | description: Scalar aggregation results  
              - name: type | type: ScalarType | description: Type of scalar aggregation  
                     - enum:
                     -     COUNT_DISTINCT: Count of distinct values
                     -     MIN: Minimum value
                     -     MAX: Maximum value
              - name: value | type: number | description: Value of the scalar aggregation  
           - name: groupedByValue | type: GroupByValueResults | description: Group by value aggregation results  
              - name: results | type: array<NestedValueAggregationResult> | description: List of value aggregations  | validation: maxItems 1000
                 - name: value | type: string | description: Value of the field  | validation: maxLength 1000
                 - name: nestedResults | type: NestedAggregationResults | description: Nested aggregations  
                    - ONE-OF: 
                       - name: values | type: ValueResults | description: Value aggregation results  
                       - name: ranges | type: RangeResults | description: Range aggregation results  
                       - name: scalar | type: ScalarResult | description: Scalar aggregation results  
                    - name: name | type: string | description: User-defined name of aggregation, matches the one provided in request  | validation: maxLength 100
                    - name: type | type: AggregationType | description: Type of aggregation that matches result  
                             - enum:
                             -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                             -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                             -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                             -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                             -     NESTED: Multi-level aggregation, where each next aggregation is nested within previous one
                    - name: fieldPath | type: string | description: Field to aggregate by, matches the one provided in request  | validation: maxLength 200
           - name: dateHistogram | type: DateHistogramResults | description: Date histogram aggregation results  
              - name: results | type: array<DateHistogramResult> | description: List of date histogram aggregations  | validation: maxItems 200
                 - name: value | type: string | description: Date in ISO 8601 format  | validation: maxLength 100
                 - name: count | type: integer | description: Count of documents in the bucket  
           - name: nested | type: NestedResults | description: Nested aggregation results  
              - name: results | type: array<Results> | description: List of nested aggregations  | validation: maxItems 1000
                 - name: results | type: Map<string,NestedResultValue> | description: List of nested aggregations  | validation: format map
                    - ONE-OF: 
                       - name: value | type: ValueResult | description: Value aggregation result  
                          - name: value | type: string | description: Value of the field  | validation: maxLength 1000
                          - name: count | type: integer | description: Count of entities with this value  | validation: format int32
                       - name: range | type: RangeResult | description: Range aggregation result  
                          - name: from | type: number | description: Inclusive lower bound of the range  | validation: format double
                          - name: to | type: number | description: Exclusive upper bound of the range  | validation: format double
                          - name: count | type: integer | description: Count of entities in this range  | validation: format int32
                       - name: scalar | type: ScalarResult | description: Scalar aggregation result  
                          - name: value | type: number | description: Value of the scalar aggregation  
                       - name: dateHistogram | type: ValueResult | description: Date histogram aggregation result  
        - name: name | type: string | description: User-defined name of aggregation as derived from search request  | validation: maxLength 100
        - name: type | type: AggregationType | description: Type of aggregation that must match provided kind as derived from search request  
        - name: fieldPath | type: string | description: Field to aggregate by as derived from search request  | validation: maxLength 200


```

### Examples

### Search Variants
Search product variants by free-text expression using Wix Query Language (WQL).

```curl
curl -X POST 'https://www.wixapis.com/stores/v3/products/search-variants' \
-H 'Content-Type: application/json' \
-H 'Authorization: <AUTH>' \
-d '{
      "search": {
        "search": {
          "expression": "t-shirt"
        },
        "cursorPaging": {
          "limit": 5
        }
      }
    }'
```

---

## JavaScript SDK

### Schema

```
 Method: wixClientAdmin.stores.readOnlyVariantsV3.searchVariants(search, options)
 Description: Search product variants using free-text search with advanced query capabilities.  Use this endpoint for complex queries that include free-text search, aggregations, or when you need faceted search results. For simple filtering, use Query Variants instead.  To learn about working with _Search_ methods, see [API Query Language](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-the-wix-api-query-language.md) and [Sorting and Paging](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-sorting-and-paging.md).  Learn more about the differences between [_Query_ and _Search_](https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-search-query-and-list-methods.md) methods.  When `search.sort` is empty (first request of a cursor search), results are ordered by `productData.updatedDate` (descending), then `productData.productId` (ascending), then `variantId` (ascending).  > **Note:** Non-visible variants, and variants related to non-visible products are filtered from results if you don't have permissions to read hidden products.
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  search
 Method parameters: 
   param name: options | type: SearchVariantsOptions  none  
        - name: fields | type: array<RequestedFields> | description: List of additional fields to include in the response. See VariantOps.RequestedFields for available options.  | validation: maxItems 100
             - enum:
             -     CURRENCY: Include currency information in product data.  Returns the currency code (ISO-4217 format) used for pricing this variant. Defaults to the site's currency unless specified in request headers.
             -     MERCHANT_DATA: Include merchant-specific data such as cost and profit information.  Returns revenue details including cost, profit, and profit margin. Requires `SCOPE.STORES.PRODUCT_READ_ADMIN` permission scope.
             -     SUBSCRIPTION_PRICES_INFO: Include subscription pricing information.  Returns calculated prices for different subscription plans with applied discounts. Only relevant for variants that are part of subscription offerings.
             -     WEIGHT_MEASUREMENT_UNIT_INFO: Include weight measurement unit information.  Returns the weight measurement unit (kg, lb, etc.) used for the variant. Useful for shipping calculations and product comparisons.
   param name: search | type: CursorSearch   | required: true 
     - name: cursorPaging | type: CursorPaging | description: Cursor pointing to page of results. When requesting 'cursor_paging.cursor', no `filter`, `sort` or `search` can be provided.  
        - name: limit | type: integer | description: Maximum number of items to return in the results.  | validation: minimum 0, maximum 1000, format int32
        - name: cursor | type: string | description: Pointer to the next or previous page in the list of results.  Pass the relevant cursor token from the `pagingMetadata` object in the previous call's response. Not relevant for the first request.  | validation: maxLength 16000
        - name: filter | type: object | description: A filter object. See documentation [here](https://bo.wix.com/wix-docs/rnd/platformization-guidelines/api-query-language#platformization-guidelines_api-query-language_defining-in-protobuf)  
        - name: sort | type: array<Sorting> | description: Sort object in the form [{"fieldName":"sortField1"},{"fieldName":"sortField2","direction":"DESC"}]  | validation: maxItems 10
           - name: fieldName | type: string | description: Name of the field to sort by.  | validation: maxLength 512
           - name: order | type: SortOrder | description: Sort order.  
                 - enum: ASC, DESC
        - name: aggregations | type: array<Aggregation> | description: Aggregations | Faceted search: refers to a way to explore large amounts of data by displaying summaries about various partitions of the data and later allowing to narrow the navigation to a specific partition.  | validation: maxItems 10
           - ONE-OF: 
              - name: value | type: ValueAggregation | description: Value aggregation  
                 - ONE-OF: 
                    - name: includeOptions | type: IncludeMissingValuesOptions | description: Options for including missing values  
                       - name: addToBucket | type: string | description: Can specify custom bucket name. Defaults are [string -> "N/A"], [int -> "0"], [bool -> "false"] ...  | validation: maxLength 20
                 - name: sortType | type: SortType | description: Should sort by number of matches or value of the field  
                         - enum:
                         -     COUNT: Should sort by number of matches
                         -     VALUE: Should sort by value of the field alphabetically
                 - name: sortDirection | type: SortDirection | description: Should sort in ascending or descending order  
                         - enum:
                         -     DESC: Should sort in descending order
                         -     ASC: Should sort in ascending order
                 - name: limit | type: integer | description: How many aggregations would you like to return? Can be between 1 and 250. 10 is the default.  | validation: format int32
                 - name: missingValues | type: MissingValues | description: Should missing values be included or excluded from the aggregation results. Default is EXCLUDE  
                         - enum:
                         -     EXCLUDE: Should missing values be excluded from the aggregation results
                         -     INCLUDE: Should missing values be included in the aggregation results
              - name: range | type: RangeAggregation | description: Range aggregation  
                 - name: buckets | type: array<RangeBucket> | description: List of range buckets, where during aggregation each entity will be placed in the first bucket where its value falls into based on provided range bounds  | validation: maxItems 50
                    - name: from | type: number | description: Inclusive lower bound of the range. Required if to is not given  
                    - name: to | type: number | description: Exclusive upper bound of the range. Required if from is not given  
              - name: scalar | type: ScalarAggregation | description: Scalar aggregation  
                 - name: type | type: ScalarType | description: Define the operator for the scalar aggregation  
                         - enum:
                         -     COUNT_DISTINCT: Count of distinct values
                         -     MIN: Minimum value
                         -     MAX: Maximum value
              - name: dateHistogram | type: DateHistogramAggregation | description: Date histogram aggregation  
                 - name: interval | type: Interval | description: Interval for date histogram aggregation  
                         - enum:
                         -     YEAR: Yearly interval
                         -     MONTH: Monthly interval
                         -     WEEK: Weekly interval
                         -     DAY: Daily interval
                         -     HOUR: Hourly interval
                         -     MINUTE: Minute interval
                         -     SECOND: Second interval
              - name: nested | type: NestedAggregation | description: Nested aggregation  
                 - name: nestedAggregations | type: array<NestedAggregationItem> | description: Flattened list of aggregations, where each next aggregation is nested within previous one  | validation: minItems 2, maxItems 3
                    - ONE-OF: 
                       - name: value | type: ValueAggregation | description: Value aggregation  
                       - name: range | type: RangeAggregation | description: Range aggregation  
                       - name: scalar | type: ScalarAggregation | description: Scalar aggregation  
                       - name: dateHistogram | type: DateHistogramAggregation | description: Date histogram aggregation  
                    - name: name | type: string | description: User-defined name of aggregation, should be unique, will appear in aggregation results  | validation: maxLength 100
                    - name: type | type: NestedAggregationType | description: Type of aggregation, client must provide matching aggregation field below  
                             - enum:
                             -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                             -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                             -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                             -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                    - name: fieldPath | type: string | description: Field to aggregate by, use dont notation to specify json path  | validation: maxLength 200
           - name: name | type: string | description: User-defined name of aggregation, should be unique, will appear in aggregation results  | validation: maxLength 100
           - name: type | type: AggregationType | description: Type of aggregation, client must provide matching aggregation field below  
                 - enum:
                 -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                 -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                 -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                 -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                 -     NESTED: Multi-level aggregation, where each next aggregation is nested within previous one
           - name: fieldPath | type: string | description: Field to aggregate by, use dot notation to specify json path  | validation: maxLength 200
        - name: search | type: SearchDetails | description: Free text to match in searchable fields  
           - name: mode | type: Mode | description: Defines how separate search terms in `expression` are combined  
                 - enum:
                 -     OR: Any of the search terms must be present
                 -     AND: All search terms must be present
           - name: expression | type: string | description: Search term or expression  | validation: maxLength 100
           - name: fields | type: array<string> | description: Fields to search in. If empty - will search in all searchable fields. Use dot notation to specify json path  | validation: maxItems 20, maxLength 200
           - name: fuzzy | type: boolean | description: Flag if should use auto fuzzy search (allowing typos by a managed proximity algorithm)  
        - name: timeZone | type: string | description: UTC offset or IANA time zone. Valid values are ISO 8601 UTC offsets, such as +02:00 or -06:00, and IANA time zone GUIDs, such as Europe/Rome  Affects all filters and aggregations returned values. You may override this behavior in a specific filter by providing timestamps including time zone. e.g. `"2023-12-20T10:52:34.795Z"`  | validation: maxLength 50
 Searchable fields:
   - field: _id | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: none | aggregatable: true | searchable: false
   - field: optionChoices.optionChoiceIds.choiceId | operators: $hasAll, $hasSome | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: optionChoices.optionChoiceIds.optionId | operators: $hasAll, $hasSome | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: barcode | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: inventoryStatus.inStock | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: inventoryStatus.preorderEnabled | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: price.actualPrice.amount | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: price.compareAtPrice.amount | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.handle | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.name | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: true
   - field: productData.productId | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.productType | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.slug | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.visible | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: productData.visibleInPos | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: sku | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: true
   - field: variantId | operators: $eq, $ne, $exists, $in, $any, $begins, $gt, $lt, $lte, $gte | sort: ASC, DESC | aggregatable: true | searchable: false
   - field: visible | operators: $eq, $ne, $exists, $in, $any | sort: ASC, DESC | aggregatable: true | searchable: false
 Return type: PROMISE<SearchVariantsResponse>
  - name: variants | type: array<ReadOnlyVariant> | description: Variants matching the search criteria.  
     - ONE-OF: 
        - name: physicalProperties | type: VariantPhysicalProperties | description: Physical properties such as weight and dimensions.  Required when the product type is `PHYSICAL`.  
           - name: weight | type: number | description: Weight of the variant for shipping calculations.  Used for shipping cost calculations and fulfillment planning. Returned only when you pass `"WEIGHT_MEASUREMENT_UNIT_INFO"` to the `fields` parameter.  | validation: minimum 0, maximum 999999999.99
           - name: pricePerUnit | type: PricePerUnit | description: Price per unit measurement information.  Allows customers to compare prices based on a standard unit (like price per kilogram or per liter). Useful for bulk products or items sold by weight or volume.  
              - name: settings | type: PricePerUnitSettings | description: Price per unit measurement settings.  Defines the unit of measurement for price comparison (e.g., per kilogram, per liter). The measurement unit must correspond to the unit set on the parent product.  
                 - name: quantity | type: number | description: Quantity. For example, to define price per per 100 grams, set this field to `100`.  | validation: minimum 0.01, maximum 999999999.99
                 - name: measurementUnit | type: MeasurementUnit | description: Measurement unit. For example, to define price per 100 grams, set this field to "G".  
                         - enum: UNSPECIFIED, ML, CL, L, CBM, MG, G, KG, MM, CM, M, SQM, OZ, LB, FLOZ, PT, QT, GAL, IN, FT, YD, SQFT
              - name: value | type: string | description: Calculated price per unit value.  Shows the variant's price normalized to the standard unit of measurement. For example, if a 500g variant costs $2 and the standard unit is 1kg, this value would be $4.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
              - name: description | type: string | description: Human-readable description of the price per unit.  For example, "per kg" or "per liter".  | validation: maxLength 100
        - name: digitalProperties | type: VariantDigitalProperties | description: Digital properties such as downloadable files.  Required when the product type is `DIGITAL`.  
           - name: digitalFile | type: SecuredMedia | description: Digital file available for download after purchase.  The file that customers receive when they purchase this digital variant.  
              - name: _id | type: string | description: Media GUID in media manager.  | validation: minLength 1, maxLength 100
              - name: fileName | type: string | description: Original file name.  | validation: minLength 1, maxLength 1000
              - name: fileSize | type: string | description: Original file size.  | validation: minLength 1, maxLength 1000, format DECIMAL_VALUE, decimalValue {"maxScale":0}
              - name: fileType | type: FileType | description: File type.  
                     - enum:
                     -     UNSPECIFIED: Unspecified file type.
                     -     SECURE_PICTURE: Secure picture file.
                     -     SECURE_VIDEO: Secure video file.
                     -     SECURE_DOCUMENT: Secure document file.
                     -     SECURE_MUSIC: Secure music file.
                     -     SECURE_ARCHIVE: Secure archive file.
                     -     SECURE_RAW: Secure raw file.
     - name: visible | type: boolean | description: Whether the variant is visible to site visitors.  Default: `true`  
     - name: sku | type: string | description: Stock keeping unit (SKU) for inventory tracking and identification.  The SKU is typically used for inventory management, order fulfillment, and product identification across different systems.  | validation: minLength 1, maxLength 40
     - name: barcode | type: string | description: Barcode for the variant, typically used for point-of-sale systems and inventory management.  Common barcode formats include UPC, EAN, and Code 128. The barcode helps with quick product identification and checkout processes.  | validation: minLength 1, maxLength 40
     - name: optionChoices | type: array<OptionChoice> | description: Product option choices that define this variant.  Each option choice represents a specific selection for a product option (like "Size: Large" or "Color: Red"). An empty list indicates this is the default variant of a product with no managed options.  | validation: minItems 0, maxItems 6
        - name: optionChoiceIds | type: OptionChoiceIds | description: Option and choice identifiers.  
           - name: optionId | type: string | description: Product option GUID.  | validation: minLength 1, maxLength 36
           - name: choiceId | type: string | description: Specific choice GUID within the option.  | validation: format GUID
        - name: optionChoiceNames | type: OptionChoiceNames | description: Human-readable option and choice names.  
           - name: optionName | type: string | description: Display name of the product option.  For example, "Size", "Color", or "Material".  | validation: minLength 1, maxLength 50
           - name: choiceName | type: string | description: Display name of the chosen option value.  For example, "Large", "Red", or "Cotton".  | validation: minLength 1, maxLength 50
           - name: renderType | type: string | description: Visual representation style for the option choice.  Determines how the option is displayed in the product selector UI. Common values include "TEXT_CHOICES", "COLOR_CHOICES", or "IMAGE_CHOICES".  | validation: maxLength 50
     - name: price | type: PriceInfo | description: Pricing information for the variant.  
        - name: actualPrice | type: FixedMonetaryAmount | description: Current selling price of the variant.  
           - name: amount | type: string | description: Monetary amount. For example, `"3.99"`, or `"-4.99"` for a negative amount.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
           - name: formattedAmount | type: string | description: Formatted monetary amount. For example, `"$3.99"`. > **Note:** Returned only when you pass `"CURRENCY"` to the `fields` array in Read-Only Variants API requests.  | validation: maxLength 20
        - name: compareAtPrice | type: FixedMonetaryAmount | description: Original price before any discounts.  Used to show customers the savings when the variant is on sale. If not set, no original price is displayed.  
     - name: revenueDetails | type: RevenueDetails | description: Revenue and cost details for business analytics.  Includes cost, profit, and profit margin calculations. Returned only when you pass `"MERCHANT_DATA"` to the `fields` parameter.  
        - name: cost | type: FixedMonetaryAmount | description: Cost of the variant for profit calculations.  The amount you pay to produce or acquire this variant.  
        - name: profit | type: FixedMonetaryAmount | description: Profit amount calculated by subtracting cost from the discounted price.  
        - name: profitMargin | type: number | description: Profit margin as a percentage of the selling price.  Calculated by dividing profit by the discounted price. The result is rounded to 4 decimal places. A value of 0.25 represents a 25% profit margin.  | validation: minimum 0, maximum 1
     - name: media | type: ProductMedia | description: Media associated with the variant.  Typically includes images, videos, or other media files specific to this variant.  
        - name: altText | type: string | description: Image alt text.  | validation: minLength 1, maxLength 1000
        - name: displayName | type: string | description: Media display name. Allows to override the default media name. Can be passed only when `setBy: url`.  | validation: maxLength 80
        - name: mediaType | type: MediaType | description: Media type.  
             - enum:
             -     IMAGE: Image media type.
             -     VIDEO: Video media type.
        - name: thumbnail | type: Thumbnail | description: Media thumbnail.  
           - name: url | type: string | description: Thumbnail URL.  | validation: format WEB_URL
           - name: height | type: integer | description: Thumbnail height.  
           - name: width | type: integer | description: Thumbnail width.  
           - name: altText | type: string | description: Thumbnail alt text.  | validation: minLength 1, maxLength 1000
        - name: uploadId | type: string | description: GUID used to upload media to Wix Media Manager.  | validation: format GUID
     - name: subscriptionPricesInfo | type: SubscriptionPricesInfo | description: Subscription pricing information when the variant is part of subscription plans.  Shows calculated prices after applying subscription discounts to the variant's price. Returned only when you pass `"SUBSCRIPTION_PRICES_INFO"` to the `fields` parameter.  
        - name: subscriptionPrices | type: array<SubscriptionPrice> | description: Pricing for different subscription plans.  Shows how the variant's price changes with different subscription intervals or discounts.  | validation: maxItems 6
           - name: subscriptionId | type: string | description: Subscription plan GUID.  | validation: format GUID
           - name: price | type: FixedMonetaryAmount | description: Variant price with subscription discount applied.  
           - name: pricePerUnit | type: SubscriptionPricePerUnit | description: Price per unit for subscription pricing.  
              - name: value | type: string | description: Calculated price per unit for the subscription.  Takes into account the subscription discount and the variant's price per unit settings.  | validation: decimalValue {"gte":"0","lte":"999999999","maxScale":3}
              - name: description | type: string | description: Description of the subscription price per unit.  | validation: maxLength 20
     - name: inventoryStatus | type: InventoryStatus | description: Current inventory and availability status.  
        - name: inStock | type: boolean | description: Whether the variant is currently in stock and available for purchase.  
        - name: preorderEnabled | type: boolean | description: Whether customers can place preorders for this variant when it's out of stock.  
     - name: productData | type: ProductFields | description: Product information for context and convenience.  Includes essential product details like name, visibility, and categories to avoid requiring separate product API calls when working with variants.  
        - ONE-OF: 
           - name: physicalProperties | type: PhysicalProperties | description: Physical product properties such as weight and dimensions.  Required when `productType` is `PHYSICAL`.  
              - name: weightMeasurementUnitInfo | type: WeightMeasurementUnitInfo | description: Weight measurement unit information for the product.  Defines the unit of measurement (kg, lb, etc.) used for product weight calculations. Returned only when you pass `"WEIGHT_MEASUREMENT_UNIT_INFO"` to the `fields` parameter.  
                 - name: weightMeasurementUnit | type: WeightUnit | description: Unit of measurement for weight.  Standard units include kilograms (KG), pounds (LB), ounces (OZ), and grams (G).  
                         - enum:
                         -     UNSPECIFIED_WEIGHT_UNIT: Weight unit can't be classified due to an error.
                         -     KG: Kilograms.
                         -     LB: Pounds.
        - name: productId | type: string | description: Product GUID.  | validation: minLength 1, maxLength 36
        - name: name | type: string | description: Product name displayed to customers.  | validation: minLength 1, maxLength 80
        - name: productType | type: ProductType | description: Type of product determining available properties and behavior.  
             - enum:
             -     PHYSICAL: Physical product.
             -     DIGITAL: Digital product.
        - name: slug | type: string | description: URL-friendly identifier for the product.  Used in product page URLs and for SEO optimization.  | validation: format URL_SLUG
        - name: visible | type: boolean | description: Whether the product is visible to site visitors.  Default: `true`  
        - name: visibleInPos | type: boolean | description: Whether the product appears in point-of-sale systems.  Default: `true` Always `false` for digital products.  
        - name: mainCategoryId | type: string | description: Primary category assignment for the product.  Determines the main category used for navigation and organization.  | validation: format GUID
        - name: currency | type: string | description: Currency used for pricing this product.  Three-letter currency code in ISO-4217 alphabetic format. Defaults to the site's currency setting unless specified in request headers. Returned only when you pass `"CURRENCY"` to the `fields` parameter.  | validation: format CURRENCY
        - name: revision | type: string | description: Revision number, which increments by 1 each time the product is updated. To prevent conflicting changes, the current revision must be passed when updating the product.  | validation: format int64
        - name: handle | type: string | description: A unique human-friendly identifier for the product.  The handle can be set by the user to ensure consistency across multiple platforms.  | validation: minLength 1, maxLength 100
     - name: variantId | type: string | description: Variant GUID. Not guaranteed to be unique across products, so it should be used together with `productData.productId` as the unique variant key.  | validation: format GUID
  - name: pagingMetadata | type: CursorPagingMetadata | description: Pagination information with cursors for next pages.  
     - name: count | type: integer | description: Number of items returned in the response.  | validation: format int32
     - name: cursors | type: Cursors | description: Cursor strings that point to the next page, previous page, or both.  
        - name: next | type: string | description: Cursor string pointing to the next page in the list of results.  | validation: maxLength 16000
        - name: prev | type: string | description: Cursor pointing to the previous page in the list of results.  | validation: maxLength 16000
     - name: hasNext | type: boolean | description: Whether there are more pages to retrieve following the current page.  + `true`: Another page of results can be retrieved. + `false`: This is the last page.  
  - name: aggregationData | type: AggregationData | description: Aggregation results for faceted search.  
     - name: results | type: array<AggregationResults> | description: key = aggregation name (as derived from search request)  | validation: maxItems 10000
        - ONE-OF: 
           - name: values | type: ValueResults | description: Value aggregation results  
              - name: results | type: array<ValueAggregationResult> | description: List of value aggregations  | validation: maxItems 250
                 - name: value | type: string | description: Value of the field  | validation: maxLength 100
                 - name: count | type: integer | description: Count of entities with this value  
           - name: ranges | type: RangeResults | description: Range aggregation results  
              - name: results | type: array<RangeAggregationResult> | description: List of ranges returned in same order as requested  | validation: maxItems 50
                 - name: from | type: number | description: Inclusive lower bound of the range  
                 - name: to | type: number | description: Exclusive upper bound of the range  
                 - name: count | type: integer | description: Count of entities in this range  
           - name: scalar | type: ScalarResult | description: Scalar aggregation results  
              - name: type | type: ScalarType | description: Type of scalar aggregation  
                     - enum:
                     -     COUNT_DISTINCT: Count of distinct values
                     -     MIN: Minimum value
                     -     MAX: Maximum value
              - name: value | type: number | description: Value of the scalar aggregation  
           - name: groupedByValue | type: GroupByValueResults | description: Group by value aggregation results  
              - name: results | type: array<NestedValueAggregationResult> | description: List of value aggregations  | validation: maxItems 1000
                 - name: value | type: string | description: Value of the field  | validation: maxLength 1000
                 - name: nestedResults | type: NestedAggregationResults | description: Nested aggregations  
                    - ONE-OF: 
                       - name: values | type: ValueResults | description: Value aggregation results  
                       - name: ranges | type: RangeResults | description: Range aggregation results  
                       - name: scalar | type: ScalarResult | description: Scalar aggregation results  
                    - name: name | type: string | description: User-defined name of aggregation, matches the one provided in request  | validation: maxLength 100
                    - name: type | type: AggregationType | description: Type of aggregation that matches result  
                             - enum:
                             -     VALUE: An aggregation where result buckets are dynamically built - one per unique value
                             -     RANGE: An aggregation, where user can define set of ranges - each representing a bucket
                             -     SCALAR: A single-value metric aggregation - e.g. min, max, sum, avg
                             -     DATE_HISTOGRAM: An aggregation, where result buckets are dynamically built - one per time interval (hour, day, week, etc.)
                             -     NESTED: Multi-level aggregation, where each next aggregation is nested within previous one
                    - name: fieldPath | type: string | description: Field to aggregate by, matches the one provided in request  | validation: maxLength 200
           - name: dateHistogram | type: DateHistogramResults | description: Date histogram aggregation results  
              - name: results | type: array<DateHistogramResult> | description: List of date histogram aggregations  | validation: maxItems 200
                 - name: value | type: string | description: Date in ISO 8601 format  | validation: maxLength 100
                 - name: count | type: integer | description: Count of documents in the bucket  
           - name: nested | type: NestedResults | description: Nested aggregation results  
              - name: results | type: array<Results> | description: List of nested aggregations  | validation: maxItems 1000
                 - name: results | type: Map<string,NestedResultValue> | description: List of nested aggregations  | validation: format map
                    - ONE-OF: 
                       - name: value | type: ValueResult | description: Value aggregation result  
                          - name: value | type: string | description: Value of the field  | validation: maxLength 1000
                          - name: count | type: integer | description: Count of entities with this value  | validation: format int32
                       - name: range | type: RangeResult | description: Range aggregation result  
                          - name: from | type: number | description: Inclusive lower bound of the range  
                          - name: to | type: number | description: Exclusive upper bound of the range  
                          - name: count | type: integer | description: Count of entities in this range  | validation: format int32
                       - name: scalar | type: ScalarResult | description: Scalar aggregation result  
                          - name: value | type: number | description: Value of the scalar aggregation  
                       - name: dateHistogram | type: ValueResult | description: Date histogram aggregation result  
        - name: name | type: string | description: User-defined name of aggregation as derived from search request  | validation: maxLength 100
        - name: type | type: AggregationType | description: Type of aggregation that must match provided kind as derived from search request  
        - name: fieldPath | type: string | description: Field to aggregate by as derived from search request  | validation: maxLength 200


```

### Examples

### Search variants
Search variants by free text expression

```javascript
import { readOnlyVariantsV3 } from "@wix/stores";

const options = {
  search: {
    search: {
      expression: "t-shirt"
    },
    cursorPaging: {
      limit: 5
    }
  }
};

async function searchVariants() {
  const response = await readOnlyVariantsV3.searchVariants(options);
}

/* Promise resolves to:
 * {
 *   "variants": [
 *     {
 *       "variantId": "6f52f714-bd4b-4c48-97cd-207cbf8233f9",
 *       "visible": true,
 *       "price": { "actualPrice": { "amount": "25.00" } },
 *       "productData": {
 *         "productId": "d7a341c4-...",
 *         "name": "T-shirt",
 *         "productType": "PHYSICAL",
 *         "slug": "t-shirt",
 *         "visible": true
 *       },
 *       "inventoryStatus": { "inStock": true }
 *     }
 *   ],
 *   "pagingMetadata": { "count": 1, "cursors": {}, "hasNext": false }
 * }
 */

```

### searchVariants (self-hosted)
Self-hosted SDK calls require you to [create a client](https://dev.wix.com/docs/sdk/articles/work-with-the-sdk/about-the-wix-client.md).

```javascript
import { createClient } from '@wix/sdk';
import { readOnlyVariantsV3 } from '@wix/stores';
// Import the auth strategy for the relevant access type
// Import the relevant host module if needed

const myWixClient = createClient ({
  modules: { readOnlyVariantsV3 },
  // Include the auth strategy and host as relevant
});


async function searchVariants(search,options) {
  const response = await myWixClient.readOnlyVariantsV3.searchVariants(search,options);
};
```

---