Kits
Kits let you sell one SKU that is fulfilled from other component SKUs. In the Public API, kit management is handled by three mutations:
kit_buildto turn a product into a kit and add component SKUskit_remove_componentsto remove specific component SKUskit_clearto remove every component and convert the kit back into a regular product
In this guide we will use a coffee starter bundle sold as COFFEE-STARTER-KIT.
The kit is made up of these component SKUs:
MUG-12OZ-BLACK- 1 mugCOFFEE-BEANS-12OZ- 2 bags of coffee beansFILTER-PAPER-100- 1 pack of filters
Note
The kit product must already exist. The component products must also exist for the same account. If you are a 3PL managing a customer account, pass customer_account_id in the mutation payloads.
Important
Kits are not warehouse-specific in the Public API. The warehouse_id field on BuildKitInput is deprecated.
1. Inspect the Current Kit Definition
Before changing anything, query the product and inspect its current kit, kit_build, and kit_components values.
query GetKitProduct($sku: String!, $customer_account_id: String) {
product(sku: $sku, customer_account_id: $customer_account_id) {
request_id
complexity
data {
id
name
sku
kit
kit_build
kit_components {
sku
quantity
}
}
}
}{
"sku": "COFFEE-STARTER-KIT"
}If this is a brand new kit, kit and kit_build will usually be false, and kit_components will be empty.
2. Build the Kit
Use kit_build when you want to add components to a kit.
In this example, we are adding the initial bundle definition:
- 1 mug
- 2 bags of coffee beans
- 1 pack of filters
mutation BuildKit($data: BuildKitInput!) {
kit_build(data: $data) {
request_id
complexity
product {
id
sku
kit
kit_build
kit_components {
sku
quantity
}
}
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT",
"kit_build": false,
"components": [
{
"sku": "MUG-12OZ-BLACK",
"quantity": 1
},
{
"sku": "COFFEE-BEANS-12OZ",
"quantity": 2
},
{
"sku": "FILTER-PAPER-100",
"quantity": 1
}
]
}
}Set kit_build to true when the kit should be treated as a build kit. Leave it out when you want to keep the product’s current kit_build value.
After the mutation succeeds, the returned product.kit_components shows the current component list.
Use kit_build: false for a regular kit and kit_build: true for a build kit. That flag affects downstream order allocation and fulfillment behavior, so inspect the current product before changing it on an existing SKU.
3. Add Another Component
Use kit_build again when you need to add a component that is not already part of the kit.
For example, if the bundle now includes a scoop:
mutation AddKitComponent($data: BuildKitInput!) {
kit_build(data: $data) {
request_id
complexity
product {
sku
kit
kit_build
kit_components {
sku
quantity
}
}
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT",
"components": [
{
"sku": "SCOOP-STAINLESS",
"quantity": 1
}
]
}
}kit_build ignores components that are already on the kit. It does not update the quantity of an existing component.
4. Remove a Component
Use kit_remove_components when a component should no longer be part of the kit.
For example, if the scoop is no longer included:
mutation RemoveKitComponents($data: RemoveKitComponentsInput!) {
kit_remove_components(data: $data) {
request_id
complexity
product {
sku
kit
kit_build
kit_components {
sku
quantity
}
}
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT",
"components": [
{
"sku": "SCOOP-STAINLESS"
}
]
}
}If the last component is removed, ShipHero clears both the kit and kit_build flags.
5. Change a Component Quantity
The Public API does not expose a dedicated kit quantity update mutation.
After you know how to add and remove components, the safest quantity-change pattern is:
- Remove the component with
kit_remove_components. - Add the same component back with
kit_buildand the new quantity.
For example, if the bundle should include 3 bags of coffee beans instead of 2, first remove that component:
mutation RemoveComponentForQuantityChange($data: RemoveKitComponentsInput!) {
kit_remove_components(data: $data) {
request_id
complexity
product {
sku
kit_components {
sku
quantity
}
}
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT",
"components": [
{
"sku": "COFFEE-BEANS-12OZ"
}
]
}
}Then add it again with the corrected quantity:
mutation ReAddKitComponent($data: BuildKitInput!) {
kit_build(data: $data) {
request_id
complexity
product {
sku
kit_components {
sku
quantity
}
}
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT",
"components": [
{
"sku": "COFFEE-BEANS-12OZ",
"quantity": 3
}
]
}
}For a complete source-of-truth sync from another system, kit_clear followed by kit_build is usually easier to reason about.
6. Clear the Kit
Use kit_clear when you want to remove the full component list and convert the kit back into a regular product.
mutation ClearKit($data: ClearKitInput!) {
kit_clear(data: $data) {
request_id
complexity
}
}{
"data": {
"sku": "COFFEE-STARTER-KIT"
}
}After clearing a kit, query the product again to confirm kit, kit_build, and kit_components.
What Can Break This Flow
- The parent SKU must already exist and be visible to the API user. If more than one account can match the SKU, pass
customer_account_id. - Each component must have a positive
quantity. - Component SKUs must already exist for the same account.
- The component list cannot include duplicate SKUs.
- A kit cannot contain itself, directly or through another kit, because that would create a component cycle.
- A product that already has inventory cannot be converted into its first kit definition.
- An assembly product cannot also contain kit components.
kit_buildis additive. It skips existing component SKUs instead of changing their quantities.- Removing the final component clears
kitandkit_build, and warehouse-level kit flags are synced back tofalse.