Product structure and how to recognize variants

In order to understand how variants work, it’s important to understand the way they are represented in the API and the Vend database. The core of the concept is that there is always a variant parent and at least one variant child.

NOTE: There is no strict limit on the number of variant children that can be involved but it’s generally recommended to keep it in the teens. Products with a large number of variants make life much harder for the frontend client apps and may reduce their performance.

Parent - child relationship

Products have a few of attributes which define the if and how they are involved in a variant product.

handle

The first and the most important thing in here is the handle. The handle is the main thing that the variant parent and all of its children have in common. The handle is also what allows us to create new variants via the API but more on that later here:

variant_parent_id and has_variants

Once a variant product is created, variant_parent_id and has_variants allow the API consumer to recognize what part a particular product is playing in the parent-child relationship.

NOTE: It’s important to remember that those are read-only attributes and they cannot be used to modify to remove a product from a variant product or reassign it to another product.

There are 3 possible combinations in which those attributes can exist:

  • Standard, simple product - no variants involved
Attribute Value
variant_parent_id null
has_variants false
  • The main product - variant parent
Attribute Value
variant_parent_id null
has_variants true
  • The main product - variant parent
Attribute Value
variant_parent_id id of the parent product
has_variants false

Variant options - variant’s unique characteristics

Apart from the “structural” attributes discussed above, there are also some which define unique properties of each variant (parent or child) - so-called variant options. In total, Vend allows the user to define 3 different options. The are usually used to describe properties like color, size, fabric, etc. A simple example of a product with the Color option defined as black will look like this in the payload:

  {
    ...
    "variant_option_one_name": "Color",
    "variant_option_one_value": "black",
    "variant_option_two_name": "",
    "variant_option_two_value": "",
    "variant_option_three_name": "",
    "variant_option_three_value": "",
    ...
  }

NOTE: It will sometimes happen that a product not involved in a variant product will have those properties populated in the payload. That means that this product used to be a variant (most likely parent) but the user turned it into a simple product. The variant options data should not be used to determine if a product IS involved in variants.

Variant property inheritance

When interrogating a product’s properties, it’s important to know that variant children don’t hold all the data related to them. Some of that data is only available on the parent.
The following attributes of a product are always inherited from the parent:

  • Name
  • Handle
  • Description
  • Tags (categories)
  • Product type
  • Supplier
  • Brand
  • Sales account code
  • Purchase account code
  • Images

All the following attributes are associated directly with the variant product object:

  • SKU
  • Pricing
  • Loyalty
  • Supplier code
  • Inventory

How to get all the variants

Based on the assumption that all the variant products (parent and the children) have the same handle it is possible to get all of them from the API by using the handle query parameter like:

https://{domain_prefix}.vendhq.com/api/products?handle={handle}

The important thing to remember here is that the API doesn’t verify in any way if all the children are actually associated with the returned parent(s) by the variant_parent_id. While this shouldn’t normally happen, it is possible to get to that state by requesting product undeletion from our Support or a broken CSV import. Because of that, the application making this request should verify the correctness of the relationship between all returned products.

How to create variants

Due to its size, this section was extracted into a separate article here: Creating variant products via the API

Gotchas

Variant updates and base_name

When updating a product which is a part of a variant product, there’s one important thing to watch out for. The name of the product delivered in the payload will be concatenated from the “root” defined as name by the user and all the variant option values, separated by the / character, e.g. "iPad case / black". If a name like that gets posted back to the API it will be stored as the name attribute and the next time it is retrieved from the API all the variant options will be duplicated like "iPad case / black / black". There are 2 ways to avoid that behavior:

  1. Avoid posting the name back to the API if you don’t really want to change it,
  2. Read the root of the name from the base_name attribute and post that as name.