Creating composite products

To create a composite product via the API, you will need some existing products to use as the composite components. For the purpose of this example, we will create a couple of new products, but those can be some other products already existing in the account. It’s just important to remember that those can’t be variant products or other composite products.

Creating new simple products

We’re doing that by sending a POST request to the /api/products endpoint with the following payload:

NOTE: This is the minimal payload required for creating a new product:

{
  "name": "composite child 1",
  "sku": "composite_child_1_sku",
  "handle": "composite_child_1_handle",
  "retail_price": 10
}

Here is the response that you will receive after this request:

{
    "product": {
        "id": "06bf537b-c783-11e6-f6b9-78603cd74bc0",
        "source_id": "",
        "variant_source_id": "",
        "handle": "composite_child_1_handle",
        "type": "",
        "has_variants": false,
        "variant_parent_id": "",
        "variant_option_one_name": "",
        "variant_option_one_value": "",
        "variant_option_two_name": "",
        "variant_option_two_value": "",
        "variant_option_three_name": "",
        "variant_option_three_value": "",
        "active": true,
        "name": "composite child 1",
        "base_name": "composite child 1",
        "description": "",
        "image": "",
        "image_large": "",
        "images": null,
        "sku": "composite_child_1_sku",
        "tags": "",
        "brand_id": "",
        "brand_name": "",
        "supplier_name": "",
        "supplier_code": "",
        "supply_price": "0.00",
        "account_code_purchase": "",
        "account_code_sales": "",
        "track_inventory": true,
        "button_order": "",
        "inventory": [],
        "price_book_entries": [
            {
                "id": "5e8a9626-ddc9-33c9-0115-9f9494c24067",
                "product_id": "06bf537b-c783-11e6-f6b9-78603cd74bc0",
                "price_book_id": "b1cc4593-f019-11e3-a0f5-b8ca3a64f8f4",
                "price_book_name": "General Price Book (All Products)",
                "type": "BASE",
                "outlet_name": "",
                "outlet_id": "",
                "customer_group_name": "",
                "customer_group_id": "b1ca8902-f019-11e3-a0f5-b8ca3a64f8f4",
                "price": 8.69565,
                "loyalty_value": null,
                "tax": 1.30435,
                "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
                "tax_rate": 0.15,
                "tax_name": "GST",
                "display_retail_price_tax_inclusive": 1,
                "min_units": "",
                "max_units": "",
                "valid_from": "",
                "valid_to": ""
            }
        ],
        "price": 8.69565,
        "tax": 1.30435,
        "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
        "tax_rate": 0.15,
        "tax_name": "GST",
        "taxes": null,
        "display_retail_price_tax_inclusive": 1,
        "updated_at": "2016-09-12 08:42:21",
        "deleted_at": ""
    }
}

The same request for the second product:

{
  "name": "composite child 2",
  "sku": "composite_child_2_sku",
  "handle": "composite_child_2_handle",
  "retail_price": 20
}

and its respective response:

{
    "product": {
        "id": "06bf537b-c783-11e6-f6b9-786077396c26",
        "source_id": "",
        "variant_source_id": "",
        "handle": "composite_child_2_handle",
        "type": "",
        "has_variants": false,
        "variant_parent_id": "",
        "variant_option_one_name": "",
        "variant_option_one_value": "",
        "variant_option_two_name": "",
        "variant_option_two_value": "",
        "variant_option_three_name": "",
        "variant_option_three_value": "",
        "active": true,
        "name": "composite child 2",
        "base_name": "composite child 2",
        "description": "",
        "image": "",
        "image_large": "",
        "images": null,
        "sku": "composite_child_2_sku",
        "tags": "",
        "brand_id": "",
        "brand_name": "",
        "supplier_name": "",
        "supplier_code": "",
        "supply_price": "0.00",
        "account_code_purchase": "",
        "account_code_sales": "",
        "track_inventory": true,
        "button_order": "",
        "inventory": [],
        "price_book_entries": [
            {
                "id": "517a49d3-dec0-e1b5-a48c-589723cc0b0f",
                "product_id": "06bf537b-c783-11e6-f6b9-786077396c26",
                "price_book_id": "b1cc4593-f019-11e3-a0f5-b8ca3a64f8f4",
                "price_book_name": "General Price Book (All Products)",
                "type": "BASE",
                "outlet_name": "",
                "outlet_id": "",
                "customer_group_name": "",
                "customer_group_id": "b1ca8902-f019-11e3-a0f5-b8ca3a64f8f4",
                "price": 17.3913,
                "loyalty_value": null,
                "tax": 2.6087,
                "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
                "tax_rate": 0.15,
                "tax_name": "GST",
                "display_retail_price_tax_inclusive": 1,
                "min_units": "",
                "max_units": "",
                "valid_from": "",
                "valid_to": ""
            }
        ],
        "price": 17.3913,
        "tax": 2.6087,
        "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
        "tax_rate": 0.15,
        "tax_name": "GST",
        "taxes": null,
        "display_retail_price_tax_inclusive": 1,
        "updated_at": "2016-09-12 08:43:59",
        "deleted_at": ""
    }
}

Creating the composite product

Now that we have some products to use as components of the composite product, we can make the request creating the final composite.

NOTE: Unlike in other parts of the API, the composite children are identified by the SKU and handle combination instead of the usual id.

Just like in a case of simple products, a composite is created by sending a POST request to the /api/products endpoint. The minimal payload should look like this:

{
	"name": "composite parent",
	"sku": "composite_parent_sku",
	"handle": "composite_parent_handle",
	"retail_price": 50,
	"composites": [{
		"sku": "composite_child_1_sku",
		"handle": "composite_child_1_handle",
		"count": 2
	}, {
		"sku": "composite_child_2_sku",
		"handle": "composite_child_2_handle",
		"count": 2
	}]
}

The API will respond with the following payload:

{
    "product": {
        "id": "06bf537b-c783-11e6-f6b9-786133d31819",
        "source_id": "",
        "variant_source_id": "",
        "handle": "composite_parent_handle",
        "type": "",
        "has_variants": false,
        "variant_parent_id": "",
        "variant_option_one_name": "",
        "variant_option_one_value": "",
        "variant_option_two_name": "",
        "variant_option_two_value": "",
        "variant_option_three_name": "",
        "variant_option_three_value": "",
        "active": true,
        "name": "composite parent",
        "base_name": "composite parent",
        "description": "",
        "image": "",
        "image_large": "",
        "images": null,
        "sku": "composite_parent_sku",
        "tags": "",
        "brand_id": "",
        "brand_name": "",
        "supplier_name": "",
        "supplier_code": "",
        "supply_price": "0.00",
        "account_code_purchase": "",
        "account_code_sales": "",
        "track_inventory": true,
        "button_order": "",
        "inventory": [],
        "price_book_entries": [
            {
                "id": "2a4e8ecb-3895-0e8f-eaed-138ddcf7792c",
                "product_id": "06bf537b-c783-11e6-f6b9-786133d31819",
                "price_book_id": "b1cc4593-f019-11e3-a0f5-b8ca3a64f8f4",
                "price_book_name": "General Price Book (All Products)",
                "type": "BASE",
                "outlet_name": "",
                "outlet_id": "",
                "customer_group_name": "",
                "customer_group_id": "b1ca8902-f019-11e3-a0f5-b8ca3a64f8f4",
                "price": 43.47826,
                "loyalty_value": null,
                "tax": 6.52174,
                "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
                "tax_rate": 0.15,
                "tax_name": "GST",
                "display_retail_price_tax_inclusive": 1,
                "min_units": "",
                "max_units": "",
                "valid_from": "",
                "valid_to": ""
            }
        ],
        "price": 43.47826,
        "tax": 6.52174,
        "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
        "tax_rate": 0.15,
        "tax_name": "GST",
        "taxes": null,
        "display_retail_price_tax_inclusive": 1,
        "updated_at": "2016-09-12 08:49:15",
        "deleted_at": ""
    }
}

Unfortunately, that payload doesn’t include all the information that the API usually provides from composite products. To get the usual payload, typical for composite payload it needs to be requested with a separate GET request to the /api/products or (/api/products/:id) endpoint. This should return a payload like:

{
    "products": [
        {
            "id": "06bf537b-c783-11e6-f6b9-786133d31819",
            "source_id": "",
            "variant_source_id": "",
            "handle": "composite_parent_handle",
            "type": "",
            "has_variants": false,
            "variant_parent_id": "",
            "variant_option_one_name": "",
            "variant_option_one_value": "",
            "variant_option_two_name": "",
            "variant_option_two_value": "",
            "variant_option_three_name": "",
            "variant_option_three_value": "",
            "active": true,
            "name": "composite parent",
            "base_name": "composite parent",
            "description": "",
            "image": "https://ppapi.vendhq.com/images/placeholder/product/no-image-white-thumb.png",
            "image_large": "https://ppapi.vendhq.com/images/placeholder/product/no-image-white-original.png",
            "images": [],
            "sku": "composite_parent_sku",
            "tags": "",
            "brand_id": "",
            "brand_name": "",
            "supplier_name": "",
            "supplier_code": "",
            "supply_price": "0.00",
            "account_code_purchase": "",
            "account_code_sales": "",
            "track_inventory": true,
            "button_order": "",
            "composites": [
                {
                    "id": "06bf537b-c783-11e6-f6b9-78603cd74bc0",
                    "handle": "composite_child_1_handle",
                    "sku": "composite_child_1_sku",
                    "count": "2.00000"
                },
                {
                    "id": "06bf537b-c783-11e6-f6b9-786077396c26",
                    "handle": "composite_child_2_handle",
                    "sku": "composite_child_2_sku",
                    "count": "2.00000"
                }
            ],
            "price_book_entries": [
                {
                    "id": "2a4e8ecb-3895-0e8f-eaed-138ddcf7792c",
                    "product_id": "06bf537b-c783-11e6-f6b9-786133d31819",
                    "price_book_id": "b1cc4593-f019-11e3-a0f5-b8ca3a64f8f4",
                    "price_book_name": "General Price Book (All Products)",
                    "type": "BASE",
                    "outlet_name": "",
                    "outlet_id": "",
                    "customer_group_name": "All Customers",
                    "customer_group_id": "b1ca8902-f019-11e3-a0f5-b8ca3a64f8f4",
                    "price": 43.47826,
                    "loyalty_value": null,
                    "tax": 6.52174,
                    "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
                    "tax_rate": 0.15,
                    "tax_name": "GST",
                    "display_retail_price_tax_inclusive": 1,
                    "min_units": "",
                    "max_units": "",
                    "valid_from": "",
                    "valid_to": ""
                }
            ],
            "price": 43.47826,
            "tax": 6.52174,
            "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
            "tax_rate": 0.15,
            "tax_name": "GST",
            "taxes": [
                {
                    "outlet_id": "b1e04bd8-f019-11e3-a0f5-b8ca3a64f8f4",
                    "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4"
                },
                {
                    "outlet_id": "b8ca3a65-0183-11e4-fbb5-2816d2677218",
                    "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4"
                },
                {
                    "outlet_id": "06bf537b-c783-11e6-f6b9-53a81bd6b215",
                    "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4"
                }
            ],
            "display_retail_price_tax_inclusive": 1,
            "updated_at": "2016-09-11 20:49:15",
            "deleted_at": ""
        }
    ]
}

WARNING: An important thing to remember, related to composite products is that a simple product used as a composite child, cannot be deleted. Before that product can be deleted, all the composite products using it as a component have to be deleted first.