Bundles
Bundles
Bundle products are composite products that contain child components -- bundled items, required options, and optional add-ons. When you add a bundle to a quote, the pricing engine automatically expands the bundle by including its bundled and required items. Optional add-ons are specified explicitly via the addOns array.
Use this guide when you need to create quotes that include bundle products. For simple standalone products, see the Standalone Products guide. For advanced scenarios such as nested bundles, dynamic product options, and per-addon overrides, see Bundles Advanced.
All examples below use the preview endpoint (POST /cpq/quotes:preview). To persist the quote, replace the URL with https://api.nue.io/cpq/quotes. The request body is identical for both modes.
Authentication
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");Example Products
The examples in this guide reference the following products from the Nue test catalog:
Bundles
Bundle | SKU | UOM | List Price | Description |
|---|---|---|---|---|
Nue Rise Edition | NUE_RISE_EDITION | User/Month | $0.00 | Starter bundle with bundled options |
Nue Gem Edition | NUE_GEM_EDITION | User/Month | $0.00 | Mid-tier bundle with required + bundled options |
Bundle Components
Component | SKU | UOM | List Price | Option Type |
|---|---|---|---|---|
Nue Platform | NUE_PLATFORM | User/Month | $15.00 | Bundled (auto-included) |
Nue on Salesforce | NUE_ON_SALESFORCE | User/Month | $29.90 | Bundled (auto-included) |
CPQ Module | CPQ_MODULE | User/Month | $10.00 | Required (auto-included) |
Billing Module | BILLING_MODULE | User/Month | $12.00 | Required (auto-included) |
Tax Manager | TAX_MANAGER | User/Month | $8.00 | Optional (specify in addOns) |
Premium Support | PREMIUM_SUPPORT | User/Month | $5.00 | Optional (specify in addOns) |
Standalone Products
Product | SKU | UOM | List Price | Revenue Model |
|---|---|---|---|---|
Implementation Service | IMPLEMENTATION_SERVICE | Hour | $250.00 | One-Time |
Key Behaviors
Behavior | Details |
|---|---|
Auto-expansion | Bundled and required items are automatically included when you add a bundle to the quote. You do not need to list them in the request. |
Optional add-ons | Optional items must be explicitly specified in the addOns array on the bundle product entry. |
Response nesting | Bundle children appear in the childrenLineItems array of the parent line item, not as top-level entries in quoteLineItems. |
$0 bundled items | Bundled items often have a $0 list price (included in the bundle price). They still appear as children in the response. |
LinkToBundleQuantity | When a component is configured with LinkToBundleQuantity, its quantity automatically matches the bundle parent's quantity. |
Quantity override | You can override the default quantity of an add-on by specifying quantity in the addOns entry, unless the component is linked to the bundle quantity. |
Invalid add-ons | Specifying a product in addOns that is not a valid option for the bundle fails the whole request with 400 INVALID_ADDON_PRODUCT. The invalid entry is not ignored and no quote is created. |
Use Case 1: Basic Bundle
Add a bundle product by SKU. The pricing engine automatically expands the bundle and includes all bundled options as children.
Scenario: Add the Nue Rise Edition bundle with 10 users. The bundle auto-populates its bundled components (Nue Platform and Nue on Salesforce).
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Rise Edition Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{ "productSku": "NUE_RISE_EDITION", "uom": "User/Month", "quantity": 10 }
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Rise Edition Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{ "productSku": "NUE_RISE_EDITION", "uom": "User/Month", "quantity": 10 }
]
}'JavaScript fetch:
const myHeaders = new Headers();
myHeaders.append("nue-api-key", "YOUR_API_KEY_HERE");
myHeaders.append("Content-Type", "application/json");
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Rise Edition Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{ productSku: "NUE_RISE_EDITION", uom: "User/Month", quantity: 10 }
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const bundle = result.quoteLineItems[0];
console.log(`Bundle: ${bundle.product.sku}, qty=${bundle.quantity}`);
console.log(`Children: ${bundle.childrenLineItems.length}`);
bundle.childrenLineItems.forEach(child => {
console.log(` ${child.product.sku}: $${child.totalPrice}`);
});
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "Rise Edition Quote",
"totalAmount": 0.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_RISE_EDITION", "name": "Nue Rise Edition" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
}
]
}
]
}The bundled items are automatically included as children. Their list price is $0.00 because they are included in the bundle. The children inherit the bundle's quantity.
Use Case 2: Bundle with Required Items
Some bundles include both bundled options and required options. Both types are auto-expanded -- you do not need to list them in the request.
Scenario: Add the Nue Gem Edition bundle. It auto-populates bundled items (Nue Platform, Nue on Salesforce) and required items (CPQ Module, Billing Module).
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Gem Edition Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{ "productSku": "NUE_GEM_EDITION", "uom": "User/Month", "quantity": 10 }
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Gem Edition Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{ "productSku": "NUE_GEM_EDITION", "uom": "User/Month", "quantity": 10 }
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Gem Edition Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{ productSku: "NUE_GEM_EDITION", uom: "User/Month", quantity: 10 }
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const bundle = result.quoteLineItems[0];
console.log(`Bundle: ${bundle.product.sku}`);
console.log(`Children: ${bundle.childrenLineItems.length}`); // 4
bundle.childrenLineItems.forEach(child => {
console.log(` ${child.product.sku} (${child.optionType}): $${child.totalPrice}`);
});
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "Gem Edition Quote",
"totalAmount": 2640.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"quantity": 10,
"listPrice": 10.00,
"listTotalPrice": 1200.00,
"totalPrice": 1200.00,
"optionType": "Required"
},
{
"product": { "sku": "BILLING_MODULE", "name": "Billing Module" },
"quantity": 10,
"listPrice": 12.00,
"listTotalPrice": 1440.00,
"totalPrice": 1440.00,
"optionType": "Required"
}
]
}
]
}Bundled items have $0 pricing (included in bundle). Required items carry their own pricing: CPQ Module at $10 x 10 x 12 = $1,200 and Billing Module at $12 x 10 x 12 = $1,440.
Use Case 3: Optional Add-Ons
Optional bundle components are not auto-included. You must specify them in the addOns array on the bundle product entry.
Scenario: Add the Nue Gem Edition bundle with an optional Tax Manager add-on.
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Gem Edition with Add-On",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "TAX_MANAGER", "quantity": 1 }
]
}
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Gem Edition with Add-On",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "TAX_MANAGER", "quantity": 1 }
]
}
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Gem Edition with Add-On",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "NUE_GEM_EDITION",
uom: "User/Month",
quantity: 10,
addOns: [
{ productSku: "TAX_MANAGER", quantity: 1 }
]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const bundle = result.quoteLineItems[0];
console.log(`Bundle children: ${bundle.childrenLineItems.length}`); // 5
bundle.childrenLineItems.forEach(child => {
console.log(` ${child.product.sku} (${child.optionType}): $${child.totalPrice}`);
});
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "Gem Edition with Add-On",
"totalAmount": 2736.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"quantity": 10,
"listPrice": 10.00,
"listTotalPrice": 1200.00,
"totalPrice": 1200.00,
"optionType": "Required"
},
{
"product": { "sku": "BILLING_MODULE", "name": "Billing Module" },
"quantity": 10,
"listPrice": 12.00,
"listTotalPrice": 1440.00,
"totalPrice": 1440.00,
"optionType": "Required"
},
{
"product": { "sku": "TAX_MANAGER", "name": "Tax Manager" },
"quantity": 1,
"listPrice": 8.00,
"listTotalPrice": 96.00,
"totalPrice": 96.00,
"optionType": "Optional"
}
]
}
]
}The Tax Manager add-on appears as a fifth child with optionType: "Optional". Its quantity is 1 as specified in the addOns array. Pricing: $8.00 x 1 x 12 = $96.00.
Use Case 4: Invalid Add-On
If you specify a product in addOns that is not a valid option for the bundle, the request fails with 400 and error code INVALID_ADDON_PRODUCT. No quote is created, and the valid parts of the bundle are not processed -- the whole request is rejected. Validate add-ons against the bundle's productOptions (from GET /catalog/products) before submitting.
Scenario: Attempt to add IMPLEMENTATION_SERVICE (a standalone product) as an add-on to the Nue Rise Edition bundle.
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Invalid Add-On Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_RISE_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "IMPLEMENTATION_SERVICE", "quantity": 1 }
]
}
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Invalid Add-On Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_RISE_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "IMPLEMENTATION_SERVICE", "quantity": 1 }
]
}
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Invalid Add-On Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "NUE_RISE_EDITION",
uom: "User/Month",
quantity: 10,
addOns: [
{ productSku: "IMPLEMENTATION_SERVICE", quantity: 1 }
]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(async response => {
const result = await response.json();
if (!response.ok) {
// 400 INVALID_ADDON_PRODUCT -- nothing was created
console.log(`${result.error}: ${result.message}`);
result.errorDetails?.forEach(e => console.log(` ${e.errorCode}: ${e.message}`));
return;
}
const bundle = result.quoteLineItems[0];
console.log(`Children: ${bundle.childrenLineItems.length}`);
})
.catch(error => console.log('Error:', error));Expected Response:
{
"status": 400,
"error": "Failed to create quote",
"message": "Bundle Nue Rise Edition doesn't include any addons with product = IMPLEMENTATION_SERVICE",
"errorDetails": [
{
"errorCode": "INVALID_ADDON_PRODUCT",
"message": "Bundle Nue Rise Edition doesn't include any addons with product = IMPLEMENTATION_SERVICE"
}
]
}The request is rejected in full. To recover, drop the invalid entry from addOns and resubmit, or look up the bundle's valid options first with GET /catalog/products.
Use Case 5: Quantity Mechanics -- LinkToBundleQuantity
When a bundle component is configured with LinkToBundleQuantity, its quantity automatically matches the parent bundle's quantity. You do not need to specify the add-on quantity -- it is derived from the bundle.
Scenario: Add the Nue Gem Edition bundle with quantity 3. The Tax Manager add-on is configured with LinkToBundleQuantity, so its quantity automatically becomes 3.
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "LinkToBundleQuantity Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 3,
"addOns": [
{ "productSku": "TAX_MANAGER" }
]
}
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "LinkToBundleQuantity Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 3,
"addOns": [
{ "productSku": "TAX_MANAGER" }
]
}
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "LinkToBundleQuantity Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "NUE_GEM_EDITION",
uom: "User/Month",
quantity: 3,
addOns: [
{ productSku: "TAX_MANAGER" }
]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const bundle = result.quoteLineItems[0];
console.log(`Bundle qty: ${bundle.quantity}`); // 3
bundle.childrenLineItems.forEach(child => {
console.log(` ${child.product.sku}: qty=${child.quantity}`); // All qty=3
});
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "LinkToBundleQuantity Quote",
"totalAmount": 1080.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 3,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 3,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 3,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"quantity": 3,
"listPrice": 10.00,
"listTotalPrice": 360.00,
"totalPrice": 360.00,
"optionType": "Required"
},
{
"product": { "sku": "BILLING_MODULE", "name": "Billing Module" },
"quantity": 3,
"listPrice": 12.00,
"listTotalPrice": 432.00,
"totalPrice": 432.00,
"optionType": "Required"
},
{
"product": { "sku": "TAX_MANAGER", "name": "Tax Manager" },
"quantity": 3,
"listPrice": 8.00,
"listTotalPrice": 288.00,
"totalPrice": 288.00,
"optionType": "Optional"
}
]
}
]
}All children have quantity 3, matching the bundle parent. The Tax Manager was not given an explicit quantity in the request -- it inherited the bundle quantity via LinkToBundleQuantity.
Use Case 6: Quantity Override on Add-On
When an add-on is not linked to the bundle quantity, you can specify an independent quantity.
Scenario: Add the Nue Gem Edition bundle with 10 users, but only 5 Premium Support add-ons.
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Add-On Quantity Override Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "PREMIUM_SUPPORT", "quantity": 5 }
]
}
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Add-On Quantity Override Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "PREMIUM_SUPPORT", "quantity": 5 }
]
}
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Add-On Quantity Override Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "NUE_GEM_EDITION",
uom: "User/Month",
quantity: 10,
addOns: [
{ productSku: "PREMIUM_SUPPORT", quantity: 5 }
]
}
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
const bundle = result.quoteLineItems[0];
console.log(`Bundle qty: ${bundle.quantity}`); // 10
bundle.childrenLineItems.forEach(child => {
console.log(` ${child.product.sku}: qty=${child.quantity}`);
});
// Bundled/Required items: qty=10 (linked to bundle)
// Premium Support: qty=5 (explicitly overridden)
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "Add-On Quantity Override Quote",
"totalAmount": 2940.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"quantity": 10,
"listPrice": 10.00,
"listTotalPrice": 1200.00,
"totalPrice": 1200.00,
"optionType": "Required"
},
{
"product": { "sku": "BILLING_MODULE", "name": "Billing Module" },
"quantity": 10,
"listPrice": 12.00,
"listTotalPrice": 1440.00,
"totalPrice": 1440.00,
"optionType": "Required"
},
{
"product": { "sku": "PREMIUM_SUPPORT", "name": "Premium Support" },
"quantity": 5,
"listPrice": 5.00,
"listTotalPrice": 300.00,
"totalPrice": 300.00,
"optionType": "Optional"
}
]
}
]
}The bundle has quantity 10, and the bundled/required items inherit that quantity. The Premium Support add-on has quantity 5 as explicitly specified. Pricing: $5.00 x 5 x 12 = $300.00.
Use Case 7: Bundle + Standalone in Same Quote
A quote can contain both bundle products and standalone products. Each is processed independently.
Scenario: Add the Nue Gem Edition bundle with an optional add-on, plus a standalone Implementation Service.
Request Body:
{
"opportunityId": "006xx000001abc123",
"name": "Bundle + Standalone Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "TAX_MANAGER", "quantity": 10 }
]
},
{ "productSku": "IMPLEMENTATION_SERVICE", "uom": "Hour", "quantity": 20 }
]
}curl:
curl -X POST 'https://api.nue.io/cpq/quotes:preview' \
-H 'nue-api-key: YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"opportunityId": "006xx000001abc123",
"name": "Bundle + Standalone Quote",
"subscriptionStartDate": "2026-01-01",
"subscriptionEndDate": "2027-01-01",
"subscriptionTermDimension": "Month",
"subscriptionTerm": 12,
"products": [
{
"productSku": "NUE_GEM_EDITION",
"uom": "User/Month",
"quantity": 10,
"addOns": [
{ "productSku": "TAX_MANAGER", "quantity": 10 }
]
},
{ "productSku": "IMPLEMENTATION_SERVICE", "uom": "Hour", "quantity": 20 }
]
}'JavaScript fetch:
const quoteData = {
opportunityId: "006xx000001abc123",
name: "Bundle + Standalone Quote",
subscriptionStartDate: "2026-01-01",
subscriptionEndDate: "2027-01-01",
subscriptionTermDimension: "Month",
subscriptionTerm: 12,
products: [
{
productSku: "NUE_GEM_EDITION",
uom: "User/Month",
quantity: 10,
addOns: [
{ productSku: "TAX_MANAGER", quantity: 10 }
]
},
{ productSku: "IMPLEMENTATION_SERVICE", uom: "Hour", quantity: 20 }
]
};
fetch('https://api.nue.io/cpq/quotes:preview', {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(quoteData)
})
.then(response => response.json())
.then(result => {
console.log(`Total Amount: $${result.quote.totalAmount}`);
console.log(`Top-level items: ${result.quoteLineItems.length}`); // 2
result.quoteLineItems.forEach(item => {
console.log(`${item.product.sku}: $${item.totalPrice}`);
if (item.childrenLineItems && item.childrenLineItems.length > 0) {
item.childrenLineItems.forEach(child => {
console.log(` └─ ${child.product.sku} (${child.optionType}): $${child.totalPrice}`);
});
}
});
})
.catch(error => console.log('Error:', error));Expected Response:
{
"quote": {
"name": "Bundle + Standalone Quote",
"totalAmount": 8600.00
},
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "NUE_ON_SALESFORCE", "name": "Nue on Salesforce" },
"quantity": 10,
"listPrice": 0.00,
"listTotalPrice": 0.00,
"totalPrice": 0.00,
"optionType": "Bundled"
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"quantity": 10,
"listPrice": 10.00,
"listTotalPrice": 1200.00,
"totalPrice": 1200.00,
"optionType": "Required"
},
{
"product": { "sku": "BILLING_MODULE", "name": "Billing Module" },
"quantity": 10,
"listPrice": 12.00,
"listTotalPrice": 1440.00,
"totalPrice": 1440.00,
"optionType": "Required"
},
{
"product": { "sku": "TAX_MANAGER", "name": "Tax Manager" },
"quantity": 10,
"listPrice": 8.00,
"listTotalPrice": 960.00,
"totalPrice": 960.00,
"optionType": "Optional"
}
]
},
{
"product": { "sku": "IMPLEMENTATION_SERVICE", "name": "Implementation Service" },
"quantity": 20,
"listPrice": 250.00,
"listTotalPrice": 5000.00,
"totalPrice": 5000.00,
"revenueModel": "One-Time",
"childrenLineItems": []
}
]
}The quoteLineItems array contains two top-level entries: the bundle (with 5 children) and the standalone product. The bundle children total $3,600 (required + optional), and the standalone Implementation Service is $5,000. Total: $8,600.00.
Response Structure
Bundle products have a nested structure. The bundle parent is a top-level entry in quoteLineItems, and its components appear in the childrenLineItems array:
{
"quoteLineItems": [
{
"product": { "sku": "NUE_GEM_EDITION", "name": "Nue Gem Edition" },
"quantity": 10,
"totalPrice": 0.00,
"childrenLineItems": [
{
"product": { "sku": "NUE_PLATFORM", "name": "Nue Platform" },
"optionType": "Bundled",
"totalPrice": 0.00
},
{
"product": { "sku": "CPQ_MODULE", "name": "CPQ Module" },
"optionType": "Required",
"totalPrice": 1200.00
},
{
"product": { "sku": "TAX_MANAGER", "name": "Tax Manager" },
"optionType": "Optional",
"totalPrice": 96.00
}
]
}
]
}Each child line item includes an optionType field:
Option Type | Description | Auto-Included |
|---|---|---|
Bundled | Included in the bundle at $0 | Yes |
Required | Required component with its own pricing | Yes |
Optional | Optional add-on, must be specified in addOns | No |
Summary
Use Case | Bundle | Key Concept |
|---|---|---|
1. Basic Bundle | NUE_RISE_EDITION | Auto-expansion of bundled items |
2. Required Items | NUE_GEM_EDITION | Required + bundled auto-expand |
3. Optional Add-Ons | NUE_GEM_EDITION + TAX_MANAGER | addOns array for optional items |
4. Invalid Add-On | NUE_RISE_EDITION + invalid | Warning returned, add-on ignored |
5. LinkToBundleQuantity | NUE_GEM_EDITION qty=3 | Children inherit parent quantity |
6. Quantity Override | NUE_GEM_EDITION + PREMIUM_SUPPORT qty=5 | Independent add-on quantity |
7. Bundle + Standalone | NUE_GEM_EDITION + IMPLEMENTATION_SERVICE | Mixed product types in one quote |
For advanced bundle scenarios including nested bundles, dynamic product options, and per-addon overrides, see Bundles Advanced.