Variants

Overview of the Variants resource and associated endpoints.

Variants represent the ways an advert can vary. For instance, an advert might come in different colors and sizes. Each color and size combination is a unique variant. These are represented by option types and option values. Option types are things such as “Color” and “Size”, and the option values are the corresponding values for these types. For example, an advert might come in “Red” and sizes “Small”, “Medium” and “Large”. This would be represented by 3 variants:

  • Color: Red, Size: Small
  • Color: Red, Size: Medium
  • Color: Red, Size: Large

Variants can represent advert variations by more than simply color and size, too. For instance, groupsets on Bike Exchange can vary based on thread, crank arm length, cassette ratio, front rotor size, rear rotor size, crankset ratio and front deraillieur.

Adverts that do not have anything to vary by still need to have a single variant - this will hold bar codes, stock, etc.


Variant IDs and External IDs

Some endpoints use a variant id (e.g. updating a variant). The id of a variant will not always be consistent after some UI operations or exporting then reimporting as CSV. Please assign an external_id to variants you want to keep track of as they relate to the data in your system. To find the current id value of a variant whose external_id you know, you can use the filtered list endpoint: GET /api/v2/client/variants?external_id=VALUE.

If you ask for a variant ID that that doesn’t exist for this authorized user, or for that specific advert if an advert ID was given, then the request will return a 404.

🧨 Deprecations

  • 29/03/2016: The upc and ean fields have been deprecated in favour of the barcode field. This is a GTIN, which can contain either UPC-12, EAN-8, EAN-13, or ITF-14 bar codes. We will still support these fields in API requests, but values will be stored under the barcode field.
  • 18/06/2019: The weight, width, length, and depth fields have been deprecated in favour of the shipping_parcel_attributes fields of the same name. We will still accept these fields in API requests, but the values will not be saved.
  • 28/06/2023:
    • The default include query param option_values has been deprecated in favour of variant_option_values. option_values does not return values from free-text option types but variant_option_values returns values from all option types.
    • The relationships.option_values input attribute has been deprecated in favour of variant_option_values.

List your variants

This endpoint will return a paginated collection of your variants.

Request

GET /api/v2/client/variants

You can filter by external_id, sku, and barcode to return only variants with that value.

GET /api/v2/client/variants?external_id=VALUE

Response

Status: 200 OK

{
  "data": [
    {
      "id": 1,
      "type": "variants",
      "attributes": {
        "count_on_hand": 10,
        "sku": "SKU002",
        "barcode": "9300601 123457",
        "fulfilment_provider": "fulfilio",
        "price": 30.0,
        "sale_price": 15.0,
        "ean": "4003994155486",
        "upc": "9300601123456",
        "max_purchase_quantity": 100,
        "min_purchase_quantity": 1
      }
    }
  ]
}

List an advert’s variants

This endpoint will return a list of a specific advert’s variants.

Request

GET /api/v2/client/adverts/1/variants

Response

Status: 200 OK
{
  "data": [
    {
      "id": 1,
      "type": "variants",
      "attributes": {
        "count_on_hand": 10,
        "sku": "SKU002",
        "barcode": "9300601 123457",
        "fulfilment_provider": "fulfilio",
        "price": 30.0,
        "sale_price": 15.0,
        "ean": "4003994155486",
        "upc": "9300601123456",
        "max_purchase_quantity": 100,
        "min_purchase_quantity": 1
      }
    }
  ]
}

Get a single variant

This endpoint shows data for a specific variant

See Variant IDs and External IDs for why an ID you thought was there might return 404.

Request

GET /api/v2/client/variants/1

You can alternatively scope the variant lookup to an advert:

GET /api/v2/client/adverts/1/variants/2

You may also opt to include the shipping dimensions, shipping profile, and catalog rule errors of this variant:

GET /api/v2/client/variants/1?include=shipping_parcel,shipping_profile,catalog_rule_errors

Response

{
  "links": {
    "self": "https://bikeexchange.com.au/api/v2/client/variants/1"
  },
  "data": {
    "id": 1,
    "type": "variants",
    "attributes": {
      "count_on_hand": 10,
      "sku": "SKU002",
      "barcode": "9300601 123457",
      "fulfilment_provider": "fulfilio",
      "price": 30.0,
      "sale_price": 15.0,
      "ean": "4003994155486",
      "upc": "9300601123456",
      "max_purchase_quantity": 100,
      "min_purchase_quantity": 1
    },
    "catalog_rule_errors": [
      {
        "field_name": "sku",
        "error_message": "SKU must be at least 8 characters long"
      }
    ],
    "relationships": {
      "variant_option_values": {
        "data": [
          {
            "type": "variant_option_values",
            "id": 30,
            "attributes": {
              "text_value": null,
            },
            "relationships": {
              "option_value": {
                "data": {
                  "type": "option_values",
                  "id": 1
                }
              }
            }
          }
        ]
      },
      "option_values": { ⬅ DEPRECATED 🧨
        "data": [
          {
            "type": "option_values",
            "id": 1
          }
        ]
      },
      "shipping_parcel": {
        "data": {
          "type": "shipping_parcels",
          "id": 1
        }
      }
    }
  },
  "included": [
    {
      "id": 30,
      "type": "variant_option_values",
      "attributes": {
        "text_value": null,
      },
      "relationships": {
        "option_value": {
          "data": {
            "type": "option_values",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_values",
      "attributes": {
        "name": "Small",
        "presentation": "Small"
      },
      "relationships": {
        "option_type": {
          "data": {
            "type": "option_types",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_types",
      "attributes": {
        "name": "Size",
        "presentation": "Size",
        "applied_to": "variant",
        "field_type": "single_select",
        "feature": false, ⬅ DEPRECATED 🧨
        "variant": true ⬅ DEPRECATED 🧨
      },
      "relationships": {
        "option_values": {
          "data": [
            {
              "type": "option_values",
              "id": 1
            }
          ]
        }
      }
    },
    {
      "type": "shipping_parcels",
      "id": 1,
      "weight": 5.0,
      "width": 8.3,
      "length": 98.3,
      "depth": 3.5,
      "mass_unit": "g",
      "distance_unit": "cm"
    }
  ]
}

Creating a variant

Creating a variant is a two-step process. First you must make a request to get a list of the variant’s possible option types and option values:

Request #1

GET /api/v2/client/adverts/1/variants/new

Response #1

Status: 200 OK
{
  "data": {
    "id": 1,
    "type": "option_types",
    "attributes": {
      "name": "Size",
      "presentation": "Size",
      "applied_to": "variant",
      "field_type": "single_select",
      "feature": false, ⬅ DEPRECATED 🧨
      "variant": true ⬅ DEPRECATED 🧨
    },
    "relationships": {
      "variant_option_values": {
        "data": [
          {
            "type": "variant_option_values",
            "id": 10,
            "attributes": {
              "text_value": null,
            },
            "relationships": {
              "option_value": {
                "data": {
                  "type": "option_values",
                  "id": 1
                }
              }
            }
          }
        ]
      },
      "option_values": { ⬅ DEPRECATED 🧨
        "data": [
          {
            "type": "option_values",
            "id": 1
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": 10,
      "type": "variant_option_values",
      "attributes": {
        "text_value": null,
      },
      "relationships": {
        "option_value": {
          "data": {
            "type": "option_values",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_values",
      "attributes": {
        "name": "Small",
        "presentation": "Small"
      },
      "relationships": {
        "option_type": {
          "data": {
            "type": "option_types",
            "id": 1
          }
        }
      }
    }
  ]
}

Once you have this information, you can create a new variant:

Request #2

POST /api/v2/client/adverts/1/variants

Input

NameTypeDescription
count_on_handstringRequired. How much of this variant is in stock currently.
infinitebooleanOptional - Indicates whether the product has infinite stock, or can be sold with 0 stock (default: false)
barcodestringThe barcode for this particular variant.
skustringThe SKU / manufacturer’s part number for this variant.
external_idstringYour system’s identifier for this variant.
notesstringOptional - not shown to shoppers
pricefloatDecimal separated with no signs or commas (i.e. 1234.00). The price of this variant, which overrides the advert’s price.
sale_pricefloatDecimal separated with no signs or commas (i.e. 1234.00). The sale price of this variant.
sale_price_start_atstringString representation of a date in the iso8601 format yyyy-MM-ddThh:mm:ss. The start date of the sale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
sale_price_end_atstringString representation of a date in the iso8601 format yyyy-MM-ddThh:mm:ss. The start date of the sale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
eanstring🧨 DEPRECATED: Please use barcode instead.
upcstring🧨 DEPRECATED: Please use barcode instead.
option_valuesarray of objects🧨 DEPRECATED: The id values of option_values for the product. The list of valid option values (with names) can be found using the /api/v2/client/adverts/1/variants/new path (see above). Please note that this is part of the relationships object rather than the attributes object.
variant_option_valuesarray of objectsThe option type values for the variant. Free-text option type values require option_type_id and text_value and single-select and multi-select option type values require option_value_id. The list of valid option types and values (with names) can be found using the Taxon API. Please note that this is part of the relationships object rather than the attributes object.
fulfilment_providerstringName of a third party fulfilment provider. This enables splitting out the variant into a separate invoice at checkout for fulfilment by the provider specified. Must be one of either fulfilio or np_fulfilment.
recommended_retail_pricefloatDecimal separated with no signs or commas (i.e. 1234.56). The recommended retail price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
wholesale_pricefloatDecimal separated with no signs or commas (i.e. 1234.56). The wholesale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
wholesale_promo_pricefloatDecimal separated with no signs or commas (i.e. 1234.56). The promotional wholesale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
wholesale_promo_price_start_atstringString representation of a date in the iso8601 format yyyy-MM-ddThh:mm:ss. The start date of the promotional wholesale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
wholesale_promo_price_end_atstringString representation of a date in the iso8601 format yyyy-MM-ddThh:mm:ss. The end date of the promotional wholesale price for the variant, this field is optional and only available for use by Headless or Connected instances of Marketplacer.
administrative_body_warningstringThis is a TGA field, (See note below). If therapeutic_goods_labelling_enabled is set to true on the associated Advert, then this field cannot be null, you must provide a valid warning. Conversely, if therapeutic_goods_labelling_enabled is set to false on the associated Advert, this field must be set to null.
intended_purposestringOptional - This is a TGA field, (See note below).
ingredientsstringOptional - This is a TGA field, (See note below).
directionsstringOptional - This is a TGA field, (See note below).
storage_instructionsstringOptional - This is a TGA field, (See note below).
suitable_forstringOptional - This is a TGA field, (See note below).
product_warningsstringOptional - This is a TGA field, (See note below).
allergen_containsstringOptional - This is a TGA field, (See note below).
allergen_may_containstringOptional - This is a TGA field, (See note below).
nutrition_informationstringOptional - This is a TGA field, (See note below).
shipping_profile_idfloatOptional - The ID of the pre-defined Shipping Profile you’d like to apply to a variant. For more information please refer to the docs here.
max_purchase_quantityfloatThe maximum purchase quantity for this item
min_purchase_quantityfloatThe minimum purchase quantity for this item
item_unitstringOptional - Used for comparable unit pricing. Represents the unit used to measure the item (e.g. ‘g’ for gram). See article for available unit options.
item_sizefloatOptional - Used for comparable unit pricing. Represents the size of the item in decimal format separated with no signs or commas (i.e. 1234.56).
comparable_unitstringOptional - Used for comparable unit pricing. Represents the comparable unit used to measure the item (e.g. ‘kg’ for kilogram). See article for available unit options.
comparable_sizefloatOptional - Used for comparable unit pricing. Represents the comparable size of the item in decimal format separated with no signs or commas (i.e. 1234.56).

Example

{
  "data": {
    "type": "variants",
    "attributes": {
      "count_on_hand": 5,
      "barcode": "9300601 123456",
      "sku": "SKU001",
      "external_id": "ABC1234",
      "fulfilment_provider": "fulfilio",
      "notes": ""
    },
    "relationships": {
      "variant_option_values": [
        {
          "type": "variant_option_values",
          "option_value_id": 1
        }
      ],
      "option_values": [ ⬅ DEPRECATED 🧨
        {
          "type": "option_values",
          "id": 1
        }
      ]
    }
  }
}

Response

Status: 200 OK
{
  "links": {
    "self": "https://bikeexchange.com.au/api/v2/client/variants/1"
  },
  "data": [
    {
      "id": 1,
      "type": "variants",
      "attributes": {
        "count_on_hand": 10,
        "sku": "SKU002",
        "barcode": "9300601 123457",
        "fulfilment_provider": "fulfilio",
        "price": 30.0,
        "sale_price": 15.0,
        "ean": "4003994155486",
        "upc": "9300601123456",
        "max_purchase_quantity": 100,
        "min_purchase_quantity": 1
      },
      "relationships": {
        "variant_option_values": {
          "data": [
            {
              "type": "variant_option_values",
              "id": 30,
              "attributes": {
                "text_value": null,
              },
              "relationships": {
                "option_value": {
                  "data": {
                    "type": "option_values",
                    "id": 1
                  }
                }
              }
            }
          ]
        },
        "option_values": { ⬅ DEPRECATED 🧨
          "data": [
            {
              "type": "option_values",
              "id": 1
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "id": 30,
      "type": "variant_option_values",
      "attributes": {
        "text_value": null,
      },
      "relationships": {
        "option_value": {
          "data": {
            "type": "option_values",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_values",
      "attributes": {
        "name": "Small",
        "presentation": "Small"
      },
      "relationships": {
        "option_type": {
          "data": {
            "type": "option_types",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_types",
      "attributes": {
        "name": "Size",
        "presentation": "Size",
        "feature": false,
        "variant": true
      },
      "relationships": {
        "option_values": {
          "data": [
            {
              "type": "option_values",
              "id": 1
            }
          ]
        }
      }
    }
  ]
}

Updating a variant

Use this endpoint to update a variant’s information, such as its count_on_hand, fulfilment_provider.

See Variant IDs and External IDs for why an ID you thought was there might return 404.

Request

PUT /api/v2/client/adverts/1/variants/1

PUT /api/v2/client/variants/1

Example

{
  "data": {
    "type": "variants",
    "attributes": {
      "count_on_hand": 0,
      "infinite": true,
      "barcode": "9300601 123456",
      "sku": "SKU001",
      "fulfilment_provider": "fulfilio"
    },
    "relationships": {
      "variant_option_values": [
        {
          "type": "variant_option_values",
          "option_value_id": 1
        }
      ],
      "option_values": [ ⬅ DEPRECATED 🧨
        {
          "type": "option_values",
          "id": "1"
        }
      ]
    }
  }
}

Response

Status: 200 OK
{
  "links": {
    "self": "https://bikeexchange.com.au/api/v2/client/variants/1"
  },
  "data": [
    {
      "id": 1,
      "type": "variants",
      "attributes": {
        "count_on_hand": 10,
        "sku": "SKU002",
        "barcode": "9300601 123457",
        "fulfilment_provider": "fulfilio",
        "price": 30.0,
        "sale_price": 15.0,
        "ean": "4003994155486",
        "upc": "9300601123456",
        "max_purchase_quantity": 100,
        "min_purchase_quantity": 1
      },
      "relationships": {
        "variant_option_values": {
          "data": [
            {
              "type": "variant_option_values",
              "id": 30,
              "attributes": {
                "text_value": null,
              },
              "relationships": {
                "option_value": {
                  "data": {
                    "type": "option_values",
                    "id": 1
                  }
                }
              }
            }
          ]
        },
        "option_values": { ⬅ DEPRECATED 🧨
          "data": [
            {
              "type": "option_values",
              "id": 1
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "id": 30,
      "type": "variant_option_values",
      "attributes": {
        "text_value": null,
      },
      "relationships": {
        "option_value": {
          "data": {
            "type": "option_values",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_values",
      "attributes": {
        "name": "Small",
        "presentation": "Small"
      },
      "relationships": {
        "option_type": {
          "data": {
            "type": "option_types",
            "id": 1
          }
        }
      }
    },
    {
      "id": 1,
      "type": "option_types",
      "attributes": {
        "name": "Size",
        "presentation": "Size",
        "feature": false,
        "variant": true
      },
      "relationships": {
        "option_values": {
          "data": [
            {
              "type": "option_values",
              "id": 1
            }
          ]
        }
      }
    }
  ]
}

Updating stock on hand for many variants

Use this endpoint to update the count_on_hand for many variants.

Request

POST /api/v2/client/variants/stock_on_hand

Example

{
  "count_on_hand": {
    "123": 2,
    "456": 10,
    "789": "INFINITE"
  }
}

Response

Status: 201 Created

Example with incorrect data

{
  "count_on_hand": {
    "123": "OTHER",
    "456": 10,
    "789": "INF"
  }
}

Response

Status: 422 Unprocessable Entity

Deleting a variant

Use this endpoint to delete a variant.

See Variant IDs and External IDs for why an ID you thought was there might return 404.

Request

DELETE /api/v2/client/adverts/1/variants/2

DELETE /api/v2/client/variants/2

Repsonse

Status: 204 No Content