> 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

# queryVariants

# Package: @wix/stores

# Namespace: readOnlyVariantsV3

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

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

## Introduction

Retrieve product variants using structured queries with cursor-based pagination.

Use this endpoint for simple filtering operations on `productData.productId` and variant identifiers.
The `id` field is deprecated and is not globally unique by itself. Use `productData.productId`
together with `variantId` as the unique variant key.
For complex queries with free-text search and aggregations, use Search Variants instead.

Up to 1,000 variants can be returned per request.

To learn about working with _Query_ endpoints, 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.

---

## JavaScript SDK

### Schema

```
 Method: wixClientAdmin.stores.readOnlyVariantsV3.queryVariants(query, options)
 Description: Retrieve product variants using structured queries with cursor-based pagination.  Use this endpoint for simple filtering operations on `productData.productId` and variant identifiers. The `id` field is deprecated and is not globally unique by itself. Use `productData.productId` together with `variantId` as the unique variant key. For complex queries with free-text search and aggregations, use Search Variants instead.  Up to 1,000 variants can be returned per request.  To learn about working with _Query_ endpoints, 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.
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  query
 Method parameters: 
   param name: options | type: QueryVariantsOptions  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: query | type: ReadOnlyVariantQuery   | required: true 
     - name: cursorPaging | type: CursorPaging | description: Cursor token pointing to a page of results. Not used in the first request. Following requests use the cursor token and not `filter` or `sort`.  
        - 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: Filter object in the following format: `"filter" : { "fieldName1": "value1", "fieldName2":{"$operator":"value2"} }` Example of operators: `$eq`, `$ne`, `$lt`, `$lte`, `$gt`, `$gte`, `$in`, `$hasSome`, `$hasAll`, `$startsWith`, `$contains`  
        - name: sort | type: array<Sorting> | description: Sort object in the following format: `[{"fieldName":"sortField1","order":"ASC"},{"fieldName":"sortField2","order":"DESC"}]`  | validation: maxItems 5
           - 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
 Query fields:
   - field: _id | operators: $eq, $ne, $in, $exists, $gt, $gte, $lt, $lte, $startsWith | sort: ASC, DESC | aggregatable: undefined | searchable: undefined
   - field: variantId | operators: $eq, $ne, $in, $exists, $gt, $gte, $lt, $lte, $startsWith | sort: ASC, DESC | aggregatable: undefined | searchable: undefined
   - field: productData.productId | operators: $eq, $ne, $in, $exists, $gt, $gte, $lt, $lte, $startsWith | sort: ASC, DESC | aggregatable: undefined | searchable: undefined
 Return type: PROMISE<QueryVariantsResponse>
  - name: variants | type: array<ReadOnlyVariant> | description: Variants matching the query 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.  | read-only: true | 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.  | read-only: true 
              - 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.  | read-only: true 
                 - name: quantity | type: number | description: Quantity. For example, to define price per per 100 grams, set this field to `100`.  | read-only: true | 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".  | read-only: true 
                         - 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.  | read-only: true | validation: decimalValue {"gte":"0","lte":"999999999.99","maxScale":3}
              - name: description | type: string | description: Human-readable description of the price per unit.  For example, "per kg" or "per liter".  | read-only: true | 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.  | read-only: true 
              - name: _id | type: string | description: Media GUID in media manager.  | read-only: true | validation: minLength 1, maxLength 100
              - name: fileName | type: string | description: Original file name.  | read-only: true | validation: minLength 1, maxLength 1000
              - name: fileSize | type: string | description: Original file size.  | read-only: true | validation: minLength 1, maxLength 1000, format DECIMAL_VALUE, decimalValue {"maxScale":0}
              - name: fileType | type: FileType | description: File type.  | read-only: true 
                     - 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`  | read-only: 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.  | read-only: true | 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.  | read-only: true | 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.  | read-only: true | validation: minItems 0, maxItems 6
        - name: optionChoiceIds | type: OptionChoiceIds | description: Option and choice identifiers.  | read-only: true 
           - name: optionId | type: string | description: Product option GUID.  | read-only: true | validation: minLength 1, maxLength 36
           - name: choiceId | type: string | description: Specific choice GUID within the option.  | read-only: true | validation: format GUID
        - name: optionChoiceNames | type: OptionChoiceNames | description: Human-readable option and choice names.  | read-only: true 
           - name: optionName | type: string | description: Display name of the product option.  For example, "Size", "Color", or "Material".  | read-only: true | validation: minLength 1, maxLength 50
           - name: choiceName | type: string | description: Display name of the chosen option value.  For example, "Large", "Red", or "Cotton".  | read-only: true | 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".  | read-only: true | validation: maxLength 50
     - name: price | type: PriceInfo | description: Pricing information for the variant.  | read-only: true 
        - name: actualPrice | type: FixedMonetaryAmount | description: Current selling price of the variant.  | read-only: true 
           - name: amount | type: string | description: Monetary amount. For example, `"3.99"`, or `"-4.99"` for a negative amount.  | read-only: true | validation: decimalValue {"gte":"0","lte":"999999999.99","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.  | read-only: true | 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.  | read-only: true 
     - 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.  | read-only: true 
        - name: cost | type: FixedMonetaryAmount | description: Cost of the variant for profit calculations.  The amount you pay to produce or acquire this variant.  | read-only: true 
        - name: profit | type: FixedMonetaryAmount | description: Profit amount calculated by subtracting cost from the discounted price.  | read-only: true 
        - 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.  | read-only: true | 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.  | read-only: true 
        - ONE-OF: 
           - name: _id | type: string | description: GUID of existing media from Wix Media Manager.  | read-only: true | validation: minLength 1, maxLength 200
           - name: url | type: string | description: Media URL.  | read-only: true | validation: format WEB_URL
        - ONE-OF: 
           - name: image | type: string | description: Product image.  | read-only: true 
           - name: video | type: string | description: Product video.  | read-only: true 
        - name: altText | type: string | description: Image alt text.  | read-only: true | 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`.  | read-only: true | validation: maxLength 80
        - name: mediaType | type: MediaType | description: Media type.  | read-only: true 
             - enum:
             -     IMAGE: Image media type.
             -     VIDEO: Video media type.
        - name: thumbnail | type: Thumbnail | description: Media thumbnail.  | read-only: true 
           - name: url | type: string | description: Thumbnail URL.  | read-only: true | validation: format WEB_URL
           - name: height | type: integer | description: Thumbnail height.  | read-only: true 
           - name: width | type: integer | description: Thumbnail width.  | read-only: true 
           - name: altText | type: string | description: Thumbnail alt text.  | read-only: true | validation: minLength 1, maxLength 1000
        - name: uploadId | type: string | description: GUID used to upload media to Wix Media Manager.  | read-only: true | 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.  | read-only: true 
        - name: subscriptionPrices | type: array<SubscriptionPrice> | description: Pricing for different subscription plans.  Shows how the variant's price changes with different subscription intervals or discounts.  | read-only: true | validation: maxItems 6
           - name: subscriptionId | type: string | description: Subscription plan GUID.  | read-only: true | validation: format GUID
           - name: price | type: FixedMonetaryAmount | description: Variant price with subscription discount applied.  | read-only: true 
           - name: pricePerUnit | type: SubscriptionPricePerUnit | description: Price per unit for subscription pricing.  | read-only: true 
              - 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.  | read-only: true | validation: decimalValue {"gte":"0","lte":"999999999.99","maxScale":3}
              - name: description | type: string | description: Description of the subscription price per unit.  | read-only: true | validation: maxLength 20
     - name: inventoryStatus | type: InventoryStatus | description: Current inventory and availability status.  | read-only: true 
        - name: inStock | type: boolean | description: Whether the variant is currently in stock and available for purchase.  | read-only: true 
        - name: preorderEnabled | type: boolean | description: Whether customers can place preorders for this variant when it's out of stock.  | read-only: true 
     - 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.  | read-only: true 
        - 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.  | read-only: true 
                 - name: weightMeasurementUnit | type: WeightUnit | description: Unit of measurement for weight.  Standard units include kilograms (KG), pounds (LB), ounces (OZ), and grams (G).  | read-only: true 
                         - 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.  | read-only: true | validation: minLength 1, maxLength 36
        - name: name | type: string | description: Product name displayed to customers.  | read-only: true | validation: minLength 1, maxLength 80
        - name: productType | type: ProductType | description: Type of product determining available properties and behavior.  | read-only: true 
             - 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.  | read-only: true | validation: format URL_SLUG
        - name: visible | type: boolean | description: Whether the product is visible to site visitors.  Default: `true`  | read-only: true 
        - name: visibleInPos | type: boolean | description: Whether the product appears in point-of-sale systems.  Default: `true` Always `false` for digital products.  | read-only: true 
        - name: mainCategoryId | type: string | description: Primary category assignment for the product.  Determines the main category used for navigation and organization.  | read-only: true | 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.  | read-only: true | 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.  | read-only: true | 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.  | read-only: true | 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.  | read-only: true | 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.  


```

### Examples

### Query variants by product and variant IDs
Retrieve specific read-only variants by product ID and variant IDs.

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

async function queryVariants() {
  const response = await readOnlyVariantsV3.queryVariants(
    {
      filter: {
        "productData.productId": {
          $eq: "9f4b9c8d-8e7f-4a6b-9c8d-1e2f3a4b5c6d",
        },
        variantId: {
          $in: [
            "a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
            "b2c3d4e5-f6a7-8b9c-0d1e-f2a3b4c5d6e7",
          ],
        },
      },
    },
    { fields: [] },
  );
  return response;
}

/* Promise resolves to:
 * {
 *   "variants": [],
 *   "pagingMetadata": {
 *     "count": 0,
 *     "hasNext": false
 *   }
 * }
 */

```

### queryVariants (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 queryVariants(query,options) {
  const response = await myWixClient.readOnlyVariantsV3.queryVariants(query,options);
};
```

---