Guides and Examples
...
Quotes
Bundles Advanced
20 min
bundles advanced this guide covers advanced bundle scenarios for the nue cpq quote api, including dynamic product options, per addon overrides, nested bundles, quantity scaling, and multi bundle quotes for basic bundle usage (auto populated children, optional add ons, simple quantities), see docid\ fri8qggg2m1jvpi qlnvi use this guide when you need to accept or reject specific add ons, override billing or term settings on individual add ons, work with bundles inside bundles, or understand how quantity scaling behaves across bundle hierarchies quantity scaling modes when a bundle parent has a quantity greater than 1, child add on quantities can scale in different ways depending on the product configuration mode behavior example (parent qty = 5, child configured qty = 2) linktobundlequantity child quantity = parent quantity child configured quantity child qty = 5 2 = 10 independent child quantity is independent of the parent child qty = 2 (unchanged) the quantity mode is configured in the product catalog on each add on's relationship to its parent it cannot be changed at quote time auto renew on nested bundles when autorenew true is set on the quote header, it applies to all products including nested bundle hierarchies each subscription created from the quote parent and children alike inherits the auto renew setting authentication setup all examples below use the following headers const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); use case 1 dynamic product options (accepted and rejected add ons) control which optional add ons are included on a bundle by listing only the desired add ons in the addons array add ons not listed are excluded from the quote bundled (required) add ons are always auto populated regardless of the addons array contents const quotedata = { opportunityid "006xx000001abc123", name "selective add ons", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, products \[ { productsku "enterprise suite", uom "user/month", quantity 50, addons \[ // accept premium support and data export { productsku "premium support", uom "user/month", quantity 50 }, { productsku "data export", uom "user/month", quantity 50 } // advanced analytics and compliance module are optional but not listed they are excluded ] } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { const parent = result quotelineitems\[0]; console log(`parent ${parent product sku}`); console log(`children ${parent childrenlineitems length}`); parent childrenlineitems foreach(child => { console log(` └─ ${child product sku} qty=${child quantity}, $${child totalprice}`); }); // includes auto populated bundled items + premium support + data export // excludes advanced analytics, compliance module (not in addons) }) catch(error => console log('error ', error)); 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" "selective add ons", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 50, "addons" \[ { "productsku" "premium support", "uom" "user/month", "quantity" 50 }, { "productsku" "data export", "uom" "user/month", "quantity" 50 } ] } ] }' the response childrenlineitems contains only the auto populated bundled items plus the two explicitly accepted add ons optional add ons not listed in addons are not included use case 2 per add on overrides (term, billing period, billing timing) individual add ons within a bundle can have their own subscriptionterm , billingperiod , and billingtiming values that differ from the parent bundle and from each other const quotedata = { opportunityid "006xx000001abc123", name "per addon overrides", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, billingperiod "annual", billingtiming "in advance", products \[ { productsku "enterprise suite", uom "user/month", quantity 50, addons \[ { productsku "premium support", uom "user/month", quantity 50, billingperiod "monthly", billingtiming "in arrears" // override billed monthly in arrears instead of annual in advance }, { productsku "data export", uom "user/month", quantity 50, subscriptionterm 6, subscriptionstartdate "2025 01 01", subscriptionenddate "2025 07 01", billingperiod "quarterly", billingtiming "in advance" // override 6 month term, quarterly billing } ] } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { const parent = result quotelineitems\[0]; console log(`parent billing ${parent billingperiod}, ${parent billingtiming}`); parent childrenlineitems foreach(child => { console log(` └─ ${child product sku} term=${child subscriptionterm}mo, billing=${child billingperiod} ${child billingtiming}, $${child totalprice}`); }); }) catch(error => console log('error ', error)); 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" "per addon overrides", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "billingperiod" "annual", "billingtiming" "in advance", "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 50, "addons" \[ { "productsku" "premium support", "uom" "user/month", "quantity" 50, "billingperiod" "monthly", "billingtiming" "in arrears" }, { "productsku" "data export", "uom" "user/month", "quantity" 50, "subscriptionterm" 6, "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2025 07 01", "billingperiod" "quarterly", "billingtiming" "in advance" } ] } ] }' result enterprise suite parent 12 month term, annual in advance billing premium support inherits the 12 month term, but uses monthly in arrears billing data export 6 month term override, quarterly in advance billing use case 3 nested bundles (bundle within a bundle) a bundle can contain another bundle as a child the inner bundle's own children (auto populated and explicit add ons) are resolved recursively in the response, the nested bundle appears inside the outer bundle's childrenlineitems , and the nested bundle has its own childrenlineitems for its children const quotedata = { opportunityid "006xx000001abc123", name "nested bundle quote", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, products \[ { productsku "enterprise suite", uom "user/month", quantity 10, addons \[ { productsku "analytics bundle", // this is itself a bundle uom "user/month", quantity 10, addons \[ { productsku "advanced dashboards", uom "user/month", quantity 10 } ] }, { productsku "premium support", 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 outer = result quotelineitems\[0]; console log(`outer bundle ${outer product sku}`); outer childrenlineitems foreach(child => { console log(` └─ ${child product sku} $${child totalprice}`); if (child childrenlineitems && child childrenlineitems length > 0) { child childrenlineitems foreach(grandchild => { console log(` └─ ${grandchild product sku} $${grandchild totalprice}`); }); } }); }) catch(error => console log('error ', error)); 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" "nested bundle quote", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 10, "addons" \[ { "productsku" "analytics bundle", "uom" "user/month", "quantity" 10, "addons" \[ { "productsku" "advanced dashboards", "uom" "user/month", "quantity" 10 } ] }, { "productsku" "premium support", "uom" "user/month", "quantity" 10 } ] } ] }' response structure enterprise suite (outer bundle) └─ analytics bundle (inner bundle) └─ \[auto populated bundled children of analytics bundle] └─ advanced dashboards (explicit add on of inner bundle) └─ premium support (add on of outer bundle) └─ \[auto populated bundled children of enterprise suite] the inner bundle's childrenlineitems array contains its own resolved children, creating a multi level hierarchy use case 4 multi level explicit add on configuration configure explicit add ons at multiple levels of a nested bundle hierarchy each level's addons array controls which optional products are included at that level const quotedata = { opportunityid "006xx000001abc123", name "multi level add on config", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, products \[ { productsku "enterprise suite", uom "user/month", quantity 20, discount 10, addons \[ { productsku "analytics bundle", uom "user/month", quantity 20, discount 15, addons \[ { productsku "advanced dashboards", uom "user/month", quantity 20 }, { productsku "real time streaming", uom "user/month", quantity 20 } ] }, { productsku "premium support", uom "user/month", quantity 20 }, { productsku "data export", uom "user/month", quantity 20 } ] } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { const outer = result quotelineitems\[0]; console log(`${outer product sku} ${outer discount}% off`); outer childrenlineitems foreach(child => { console log(` └─ ${child product sku} ${child discount}% off, $${child totalprice}`); if (child childrenlineitems && child childrenlineitems length > 0) { child childrenlineitems foreach(gc => { console log(` └─ ${gc product sku} ${gc discount}% off, $${gc totalprice}`); }); } }); }) catch(error => console log('error ', error)); 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" "multi level add on config", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 20, "discount" 10, "addons" \[ { "productsku" "analytics bundle", "uom" "user/month", "quantity" 20, "discount" 15, "addons" \[ { "productsku" "advanced dashboards", "uom" "user/month", "quantity" 20 }, { "productsku" "real time streaming", "uom" "user/month", "quantity" 20 } ] }, { "productsku" "premium support", "uom" "user/month", "quantity" 20 }, { "productsku" "data export", "uom" "user/month", "quantity" 20 } ] } ] }' discount propagation enterprise suite has 10% off its direct children ( premium support , data export ) inherit 10% analytics bundle has its own 15% off (overrides parent's 10%) its children ( advanced dashboards , real time streaming ) inherit 15% use case 5 large bundle quantity (linktobundlequantity scaling) when the parent bundle quantity is large, child add ons configured with linktobundlequantity scale their quantities proportionally this example uses a parent quantity of 5 to demonstrate the scaling behavior const quotedata = { opportunityid "006xx000001abc123", name "large bundle quantity scaling", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, products \[ { productsku "enterprise suite", uom "user/month", quantity 5, addons \[ { productsku "premium support", uom "user/month", quantity 1 }, { productsku "data export", uom "user/month", quantity 2 } ] } ] }; fetch('https //api nue io/cpq/quotes\ preview', { method 'post', headers myheaders, body json stringify(quotedata) }) then(response => response json()) then(result => { const parent = result quotelineitems\[0]; console log(`parent ${parent product sku}, qty=${parent quantity}`); parent childrenlineitems foreach(child => { console log(` └─ ${child product sku} qty=${child quantity}, $${child totalprice}`); // if linktobundlequantity // premium support 5 1 = 5 // data export 5 2 = 10 // if independent // premium support 1 // data export 2 }); }) catch(error => console log('error ', error)); 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" "large bundle quantity scaling", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 5, "addons" \[ { "productsku" "premium support", "uom" "user/month", "quantity" 1 }, { "productsku" "data export", "uom" "user/month", "quantity" 2 } ] } ] }' result with linktobundlequantity mode premium support resolved quantity = 5 1 = 5 data export resolved quantity = 5 2 = 10 result with independent mode premium support resolved quantity = 1 (as specified) data export resolved quantity = 2 (as specified) the actual scaling behavior depends on how the add on relationship is configured in the product catalog check the response quantity field on each child line item to confirm the resolved quantity use case 6 two bundles and a standalone in the same quote a quote can contain multiple bundles and standalone products each bundle is resolved independently, and all products are priced together on the same quote const quotedata = { opportunityid "006xx000001abc123", name "multi bundle + standalone", subscriptionstartdate "2025 01 01", subscriptionenddate "2026 01 01", subscriptiontermdimension "month", subscriptionterm 12, discount 5, products \[ { productsku "enterprise suite", uom "user/month", quantity 25, discount 10, addons \[ { productsku "premium support", uom "user/month", quantity 25 }, { productsku "data export", uom "user/month", quantity 25 } ] }, { productsku "analytics bundle", uom "user/month", quantity 15, addons \[ { productsku "advanced dashboards", uom "user/month", quantity 15 } ] }, { productsku "nue on salesforce", 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 => { console log(`total $${result quote totalamount}`); console log(`top level items ${result quotelineitems length}`); // 3 result quotelineitems foreach(item => { const children = item childrenlineitems || \[]; if (children length > 0) { console log(`bundle ${item product sku} (${item discount}% off, ${children length} children)`); children foreach(child => { console log(` └─ ${child product sku} qty=${child quantity}, $${child totalprice}`); }); } else { console log(`standalone ${item product sku} ${item discount}% off, $${item totalprice}`); } }); }) catch(error => console log('error ', error)); 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" "multi bundle + standalone", "subscriptionstartdate" "2025 01 01", "subscriptionenddate" "2026 01 01", "subscriptiontermdimension" "month", "subscriptionterm" 12, "discount" 5, "products" \[ { "productsku" "enterprise suite", "uom" "user/month", "quantity" 25, "discount" 10, "addons" \[ { "productsku" "premium support", "uom" "user/month", "quantity" 25 }, { "productsku" "data export", "uom" "user/month", "quantity" 25 } ] }, { "productsku" "analytics bundle", "uom" "user/month", "quantity" 15, "addons" \[ { "productsku" "advanced dashboards", "uom" "user/month", "quantity" 15 } ] }, { "productsku" "nue on salesforce", "uom" "user/month", "quantity" 10 } ] }' result enterprise suite bundle 10% product level discount (overrides the 5% header discount) its children inherit 10% analytics bundle bundle no product level discount, so it receives the 5% header discount its children inherit 5% nue on salesforce standalone no product level discount, so it receives the 5% header discount the quote totalamount is the sum of all line items across both bundles and the standalone product response structure for nested bundles nested bundles produce a multi level childrenlineitems hierarchy { "quote" { "totalamount" 12345 00 }, "quotelineitems" \[ { "product" { "sku" "enterprise suite" }, "quantity" 10, "totalprice" 8000 00, "childrenlineitems" \[ { "product" { "sku" "analytics bundle" }, "quantity" 10, "totalprice" 3000 00, "childrenlineitems" \[ { "product" { "sku" "advanced dashboards" }, "quantity" 10, "totalprice" 1200 00, "childrenlineitems" \[] } ] }, { "product" { "sku" "premium support" }, "quantity" 10, "totalprice" 500 00, "childrenlineitems" \[] } ] } ] } key points each level of nesting adds another childrenlineitems array leaf products (non bundles) have an empty childrenlineitems array the parent's totalprice reflects the combined pricing of the entire bundle hierarchy as configured in the catalog summary scenario what to specify key behavior accept/reject optional add ons list desired add ons in addons unlisted optional add ons are excluded per addon billing overrides set billingperiod , billingtiming , subscriptionterm on individual add ons overrides apply to that add on only nested bundles add a bundle sku inside another bundle's addons with its own addons resolved recursively; multi level childrenlineitems multi level discounts set discount on each bundle level each level's discount propagates to its own children linktobundlequantity scaling set parent quantity; child quantities multiply depends on catalog configuration multiple bundles in one quote list each bundle in products array each resolved independently next steps docid\ fri8qggg2m1jvpi qlnvi basic bundle usage and fundamentals docid\ y9awhgt5iyiblymwve6nx apply header, parent, and line level discretionary discounts docid\ wwo0bzasgs6mdcue g kl configure term lengths, billing periods, and renewal settings docid\ bc idxynwaus7o9efycwq return to the full api reference