Guides and Examples
...
Orders
Creating Draft Change Orders
42 min
this guide provides comprehensive instructions for creating draft change orders using the nue lifecycle management api learn how to modify existing subscriptions through quantity updates, renewals, upgrades, downgrades, and other subscription lifecycle changes prerequisites before you begin, ensure you have a valid nue api key with change order permissions asset numbers (sub xxxxxx format) for existing subscriptions to modify understanding of subscription change types and their implications basic knowledge of rest apis and json customer timezone information for accurate date calculations authentication all change order operations require authentication using your nue api key in the nue api key header const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); change order overview change orders modify existing subscriptions through the /change orders endpoint unlike regular orders that create new subscriptions, change orders reference existing assets and apply specific change types try it now https //api docs nue io/create change order important limitations ⚠️ draft change orders have specific limitations compared to regular draft orders no description fields change orders do not support description fields at any level no price tag support change orders do not accept pricetagids or pricetagcodes fields asset based structure changes are applied to existing assets, not new product configurations limited customization only change type specific parameters are supported these limitations ensure change orders maintain data integrity when modifying existing subscriptions change types reference the nue api supports 10 different change types, plus a products array for adding new products change type purpose required fields use case updatequantity change subscription quantity quantity , startdate scale subscription up/down updateterm modify subscription term term extend/shorten contract renew renew expiring subscription renewalterm continue subscription coterm align with another subscription cotermdate synchronize end dates cancel terminate subscription cancellationdate end subscription early convertfreetrial convert trial to paid startdate , term monetize trial users upgrade move to higher tier product targetpricebookentryid , startdate increase service level downgrade move to lower tier product targetpricebookentryid , startdate reduce service level swap switch to different product targetpricebookentryid , startdate change product type reconfigure add bundle add ons startdate , addons self service bundle management additionally, the products array allows adding completely new products (cross sell) alongside asset changes see the docid\ zsxm12tfkla93eqzgigm9 section below basic change order structure all change orders follow this base structure const changeorderrequest = { // optional configuration options options { previewinvoice true, // generate billing preview (default true) calculatetax false // calculate tax amounts (default false) }, // optional timezone for date calculations timezone "america/new york", // optional custom fields at order level "ruby custom c" "value1", "department c" "engineering", // required array of asset changes assetchanges \[ { changetype "updatequantity", // required change type assetnumber "sub 000001", // required asset to modify // additional fields based on change type } ], // optional array of new products to add (cross sell) products \[ { pricebookentryid "01uql000009tsn7yac", // required product to add quantity 3, // required quantity subscriptionstartdate "2025 02 15", // required start date subscriptionterm 12 // required term in months // either subscriptionterm or cotermasset is required } ] }; custom fields on change orders setting custom fields at order level custom fields can be set at the order level for change orders these fields must be synced via the business objects page in nue settings before they can be used important limitation custom fields are only supported at the order level for change orders unlike draft orders, change orders do not support custom fields on individual asset changes const changeorderwithcustomfields = { // order level custom fields "ruby custom c" "value1", "department c" "engineering", "projectcode c" "change 2025 001", "changereason c" "customer request", options { previewinvoice true, calculatetax false }, timezone "america/new york", assetchanges \[ { changetype "swap", assetnumber "sub 00001098", targetpricebookentryid "01uec000009nkzmiac", startdate "2025 08 18" }, { changetype "swap", assetnumber "sub 00001099", targetpricebookentryid "01uec000009nkzuiac", startdate "2025 08 18" } ] }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(changeorderwithcustomfields) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ change order created with custom fields'); console log(`change order id ${result data order id}`); } }) catch(error => console log('error ', error)); request body schema required fields field type description example assetchanges array list of asset changes to apply see asset change schema below optional fields field type description example options previewinvoice boolean generate billing preview (default true) true options calculatetax boolean calculate tax amounts (default false) false timezone string customer timezone for calculations "america/new york" asset change schema field type required description changetype string yes type of change (see enum above) assetnumber string yes asset identifier (sub xxxxxx format) change type specific fields updatequantity quantity (number, required) quantity delta (positive to add, negative to reduce) startdate (string, required) change start date updateterm term (number, required) new term in months renew renewalterm (number, required) renewal term in months coterm cotermdate (string, required) target coterm date cancel cancellationdate (string, required) cancellation date convertfreetrial startdate (string, required) conversion start date term (number, required) subscription term in months overridetrialend (boolean, optional) override trial end behavior upgrade/downgrade/swap targetpricebookentryid (string, required) target product id startdate (string, required) change start date product relationship requirements upgrade, downgrade, and swap operations require a valid product relationship to be configured in the catalog between the source and target products how it works relationship lookup when processing a change order, the system validates that a productrelationship exists upgrades/swaps looks for a relationship from source product → target product downgrades looks for an "upgrade" relationship from target product → source product (reversed direction) uom validation the system validates unit of measure compatibility based on the relationship's baseuomrange and targetuomrange settings (e g , "any", "sameuomonly", or specific uom lists) same price swap if samepriceswap true is configured on the productrelationship, the system automatically applies same price swap behavior this is derived from the catalog configuration price tags any price tags (price dimensions) configured on the productrelationship are automatically applied during pricing error response if no valid product relationship exists between the source and target products { "status" 400, "error" "bad request", "code" "invalid parameter", "message" "no valid product relationship found for upgrade from product sku 'basic plan' (uom user/month) to product sku 'pro plan' (uom user/month)" } catalog configuration required before using upgrade, downgrade, or swap change types, ensure that product relationships are defined between the source and target products the relationship type matches the intended change type (upgrade, downgrade, or swap) uom ranges are configured appropriately if products have multiple uoms price tags are attached to the relationship if special pricing should apply reconfigure startdate (string, required) change start date addons (array, required) array of add on configurations productoptionid (string, required) product option id for bundle add on reconfigureeffectivedate (string, required) when add on change takes effect productoptionquantity (number, required) quantity of the add on ⚠️ important restriction reconfigure change orders cannot be combined with other change types in a single transaction products array (new product / cross sell) the products array is a separate top level field alongside assetchanges used for adding new products to the account field type required description pricebookentryid string yes price book entry id identifying the product to add quantity number yes quantity to add (must be positive) subscriptionstartdate string yes effective start date (yyyy mm dd) subscriptionterm number one of term/cotermasset subscription term in months mutually exclusive with cotermasset cotermasset string one of term/cotermasset existing subscription number (e g sub 000200 ) to co term with mutually exclusive with subscriptionterm autorenew boolean no whether the subscription should auto renew defaultrenewalterm number no renewal term in months when auto renew is enabled billingtiming string no billing timing, e g in advance , in arrears billingperiod string no billing frequency, e g month , year billcycleday string no day of the billing cycle billcyclestartmonth string no starting month for annual billing cycles description string no custom description pricetagids array no price tag ids to apply discounts pricetagcodes array no price tag codes (alternative to ids) customfields object no custom field values to populate on the order product addons array no bundle add ons to include (see add on structure below) new product add on structure field type required description productoptionid string yes product option id for dynamic options, use the composite id {productoptionid} {pricebookentryid} productoptionquantity number yes quantity of the add on subscriptionterm number no term in months if different from parent cotermasset string no co term with an existing subscription subscriptionstartdate string no start date if different from parent billingtiming string no billing timing override billingperiod string no billing period override billcycleday string no bill cycle day override billcyclestartmonth string no bill cycle start month override pricetagids array no price tag ids pricetagcodes array no price tag codes addons array no nested add ons (recursive) customfields object no custom field values pricing fields are calculated automatically fields like netsalesprice , salesprice , subtotal , listtotal , totalprice , totalamount , tax , and discountamount are calculated by the pricing engine and cannot be set on the request the api will reject requests that include these fields advanced change order scenarios update subscription quantity scale an existing subscription up or down const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); const quantitychangeorder = { timezone "america/new york", assetchanges \[ { changetype "updatequantity", assetnumber "sub 000293", quantity 150, startdate "2025 02 01" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(quantitychangeorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ quantity change order created successfully'); console log('change order id ', result data order? id); } }) catch(error => console log('quantity change failed ', error)); update subscription term modify the term length of an existing subscription const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); const termupdateorder = { timezone "america/new york", assetchanges \[ { changetype "updateterm", assetnumber "sub 000293", term 24 } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(termupdateorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ term update order created successfully'); console log('change order id ', result data order? id); } }) catch(error => console log('term update failed ', error)); renew subscription extend an expiring subscription const renewalorder = { timezone "america/new york", assetchanges \[ { changetype "renew", assetnumber "sub 000293", renewalterm 12 } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(renewalorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ renewal order created successfully'); } }) catch(error => console log('renewal failed ', error)); convert free trial to paid subscription monetize trial users by converting to paid plans const trialconversionorder = { timezone "america/new york", assetchanges \[ { changetype "convertfreetrial", assetnumber "sub 000293", startdate "2025 03 21", term 12, overridetrialend false } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(trialconversionorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ trial conversion successful'); } }) catch(error => console log('trial conversion failed ', error)); upgrade subscription move customer to a higher tier product const upgradeorder = { timezone "america/new york", assetchanges \[ { changetype "upgrade", assetnumber "sub 000293", targetpricebookentryid "01u4x000005yw0baas", startdate "2025 03 21" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(upgradeorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ upgrade order created successfully'); } }) catch(error => console log('upgrade failed ', error)); downgrade subscription move customer to a lower tier product const downgradeorder = { timezone "america/new york", assetchanges \[ { changetype "downgrade", assetnumber "sub 000293", targetpricebookentryid "01u4x000005yw0caas", startdate "2025 03 21" } ], options { previewinvoice true, calculatetax false } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(downgradeorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ downgrade order created successfully'); } }) catch(error => console log('downgrade failed ', error)); co terminate multiple subscriptions align subscription end dates for easier management const cotermorder = { timezone "america/new york", assetchanges \[ { changetype "coterm", assetnumber "sub 000293", cotermdate "2025 07 20" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(cotermorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ co termination order created'); } }) catch(error => console log('co termination failed ', error)); cancel subscription terminate a subscription with proper notice const cancellationorder = { timezone "america/new york", assetchanges \[ { changetype "cancel", assetnumber "sub 000293", cancellationdate "2025 03 21" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(cancellationorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ cancellation order created'); } }) catch(error => console log('cancellation failed ', error)); reconfigure bundle subscription add product options (add ons) from existing bundle subscriptions const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); const reconfigureorder = { timezone "america/new york", assetchanges \[ { changetype "reconfigure", assetnumber "sub 000050", startdate "2025 08 26", addons \[ { productoptionid "a0g7z000007guxuaam", reconfigureeffectivedate "2025 08 26", productoptionquantity 2 } ] } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(reconfigureorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ bundle reconfiguration successful'); console log('change order id ', result data order? id); } }) catch(error => console log('bundle reconfiguration failed ', error)); product swap switch to a different product at the same level const swaporder = { timezone "america/new york", assetchanges \[ { changetype "swap", assetnumber "sub 000293", targetpricebookentryid "01u4x000005yw0daas", startdate "2025 03 21" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(swaporder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ product swap order created'); } }) catch(error => console log('product swap failed ', error)); new product (cross sell) add a completely new product as part of a change order new products are specified in a separate products array alongside the assetchanges array supports standalone products and full bundle hierarchies with configured and dynamic add ons important the products array must be accompanied by at least one entry in the assetchanges array (e g , cancel, updatequantity, renew) you cannot submit a change order with only new products basic new product cancel an existing subscription and add a new product with a 12 month term const newproductorder = { timezone "america/new york", assetchanges \[ { changetype "cancel", assetnumber "sub 000192", cancellationdate "2025 02 15" } ], products \[ { pricebookentryid "01uql000009tsn7yac", quantity 3, subscriptionstartdate "2025 02 15", subscriptionterm 12 } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(newproductorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('new product change order created successfully'); console log('change order id ', result data order? id); } }) catch(error => console log('new product change order failed ', error)); new product with bundle add ons add a new bundle product with configured and dynamic add ons const bundlenewproductorder = { timezone "america/new york", assetchanges \[ { changetype "cancel", assetnumber "sub 000192", cancellationdate "2025 02 15" } ], products \[ { pricebookentryid "01uql000009tsn7yac", quantity 3, subscriptionstartdate "2025 02 15", subscriptionterm 12, addons \[ { // configured add on productoptionid "a0jql00000jxnavyaz", productoptionquantity 3 }, { // dynamic add on use composite id {productoptionid} {pricebookentryid} productoptionid "a0jql00000jxnavyaz 01uql00000cxugcyap", productoptionquantity 10 } ] } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(bundlenewproductorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('bundle new product change order created'); } }) catch(error => console log('bundle new product failed ', error)); new product co termed with existing subscription align the new product's end date to an existing subscription instead of specifying a term const cotermnewproductorder = { timezone "america/new york", assetchanges \[ { changetype "cancel", assetnumber "sub 000192", cancellationdate "2025 02 15" } ], products \[ { pricebookentryid "01uql000009tsn7yac", quantity 5, subscriptionstartdate "2025 02 15", // co terminate with existing subscription instead of fixed term cotermasset "sub 000200" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(cotermnewproductorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('co termed new product change order created'); } }) catch(error => console log('co termed new product failed ', error)); multiple changes in single order apply multiple changes across different subscriptions const multichangeorder = { timezone "america/new york", assetchanges \[ { changetype "updatequantity", assetnumber "sub 000001", quantity 200, startdate "2025 07 01" }, { changetype "upgrade", assetnumber "sub 000002", targetpricebookentryid "01uql000009tsn5yac", startdate "2025 07 01" }, { changetype "cancel", assetnumber "sub 000003", cancellationdate "2025 07 31" } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/change orders', { method 'post', headers myheaders, body json stringify(multichangeorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('✅ multiple changes applied successfully'); } }) catch(error => console log('multiple changes failed ', error)); change order service class implement a comprehensive service for change order management class changeorderservice { constructor(apikey) { this apikey = apikey; this headers = new headers(); this headers append("nue api key", apikey); this headers append("content type", "application/json"); } async createchangeorder(changeorderinput) { try { // step 1 validate change order data const validatedorder = this validatechangeorderdata(changeorderinput); // step 2 apply business rules and defaults const enrichedorder = this enrichchangeorderdata(validatedorder); // step 3 submit change order const changeorder = await this submitchangeorder(enrichedorder); // step 4 process results const processedresult = this processchangeorderresult(changeorder); return { success true, order processedresult order, assets processedresult assets, previews processedresult previews, warnings processedresult warnings, summary this generatechangeordersummary(processedresult) }; } catch (error) { console error('change order creation failed ', error); return { success false, error error message, orderinput changeorderinput }; } } validatechangeorderdata(orderinput) { const errors = \[]; // required field validation if (!orderinput timezone) { errors push('time zone is required for change orders'); } if (!orderinput assetchanges || orderinput assetchanges length === 0) { errors push('at least one asset change is required'); } // asset change validation orderinput assetchanges? foreach((change, index) => { const changepath = `asset change ${index + 1}`; if (!change changetype) { errors push(`${changepath} change type is required`); } if (!change assetnumber) { errors push(`${changepath} asset number is required`); } // validate asset number format if (change assetnumber && !change assetnumber match(/^sub \d{6}$/)) { errors push(`${changepath} asset number must be in format sub xxxxxx`); } // change type specific validation this validatechangetyperequirements(change, changepath, errors); }); if (errors length > 0) { throw new error(`change order validation failed \n${errors join('\n')}`); } return orderinput; } validatechangetyperequirements(change, changepath, errors) { const changetype = change changetype; switch (changetype) { case 'updatequantity' if (change quantity === undefined || change quantity === null || change quantity === 0) { errors push(`${changepath} quantity (delta) is required and cannot be 0 for updatequantity`); } if (!change startdate) { errors push(`${changepath} start date is required for updatequantity`); } break; case 'updateterm' if (!change term || change term <= 0) { errors push(`${changepath} term must be greater than 0 for updateterm`); } break; case 'renew' if (!change renewalterm || change renewalterm <= 0) { errors push(`${changepath} renewal term must be greater than 0 for renew`); } break; case 'coterm' if (!change cotermdate) { errors push(`${changepath} co term date is required for coterm`); } break; case 'cancel' if (!change cancellationdate) { errors push(`${changepath} cancellation date is required for cancel`); } break; case 'convertfreetrial' if (!change startdate) { errors push(`${changepath} start date is required for convertfreetrial`); } if (!change term || change term <= 0) { errors push(`${changepath} term must be greater than 0 for convertfreetrial`); } break; case 'upgrade' case 'downgrade' case 'swap' if (!change targetpricebookentryid) { errors push(`${changepath} target price book entry id is required for ${changetype}`); } if (!change startdate) { errors push(`${changepath} start date is required for ${changetype}`); } break; case 'reconfigure' if (!change startdate) { errors push(`${changepath} start date is required for reconfigure`); } if (!change addons || !array isarray(change addons) || change addons length === 0) { errors push(`${changepath} at least one add on is required for reconfigure`); } else { change addons foreach((addon, addonindex) => { const addonpath = `${changepath} add on ${addonindex + 1}`; if (!addon productoptionid) { errors push(`${addonpath} product option id is required`); } if (!addon reconfigureeffectivedate) { errors push(`${addonpath} reconfigure effective date is required`); } if (!addon productoptionquantity || addon productoptionquantity <= 0) { errors push(`${addonpath} product option quantity must be greater than 0`); } }); } break; default errors push(`${changepath} invalid change type ${changetype}`); } } enrichchangeorderdata(orderinput) { return { orderinput, // set default options if not provided options { previewinvoice true, calculatetax false, orderinput options } }; } async submitchangeorder(orderdata) { const response = await fetch('https //api nue io/change orders', { method 'post', headers this headers, body json stringify(orderdata) }); if (!response ok) { const errortext = await response text(); throw new error(`api error ${response status} ${errortext}`); } const result = await response json(); if (result status !== 'success') { throw new error(`change order creation failed ${result message || 'unknown error'}`); } return result; } processchangeorderresult(apiresult) { return { order apiresult data order, assets apiresult data assets || \[], previews apiresult data previews || \[], warnings apiresult data warnings || \[] }; } generatechangeordersummary(result) { const order = result order; const assets = result assets; // group changes by type const changetypes = assets reduce((acc, asset) => { const type = asset changetype || 'unknown'; acc\[type] = (acc\[type] || 0) + 1; return acc; }, {}); // calculate billing impact const totalbillingimpact = result previews reduce((sum, preview) => { return sum + (preview\ netamount || 0); }, 0); return { orderid order id, effectivedate order effectivedate, totalchanges assets length, changetypes changetypes, billingimpact totalbillingimpact, haswarnings result warnings length > 0, warningcount result warnings length }; } } // usage example const changeorderservice = new changeorderservice("your api key here"); const subscriptionupgrade = { timezone "america/new york", assetchanges \[ { changetype "upgrade", assetnumber "sub 000001", targetpricebookentryid "01uql000009tsn6yac", startdate "2025 08 01" } ] }; changeorderservice createchangeorder(subscriptionupgrade) then(result => { if (result success) { console log('\n🎉 change order created successfully!'); console log(`order id ${result summary orderid}`); console log(`changes applied ${result summary totalchanges}`); console log(`billing impact ${result summary billingimpact >= 0 ? '+' ''}$${result summary billingimpact}`); if (result summary haswarnings) { console log(`\n⚠️ ${result summary warningcount} warnings to review`); } } else { console error('❌ change order failed ', result error); } }); request body schema required fields field type description example assetchanges array list of asset changes to apply see asset change schema below asset change schema field type required description changetype string yes type of change (see enum above) assetnumber string yes asset identifier (sub xxxxxx format) change type specific fields updatequantity quantity (number, required) quantity delta (positive to add, negative to reduce) startdate (string, required) change start date updateterm term (number, required) new term in months renew renewalterm (number, required) renewal term in months upgrade/downgrade/swap targetpricebookentryid (string, required) target product id startdate (string, required) change start date ⚠️ important upgrade, downgrade, and swap operations do not support ramp tags on price book entries use products with standard pricing for these change types reconfigure startdate (string, required) change start date addons (array, required) array of add on configurations productoptionid (string, required) product option id for bundle add on reconfigureeffectivedate (string, required) when add on change takes effect productoptionquantity (number, required) quantity of the add on response structure success response (201 created) { "status" "success", "data" { "order" { "id" "change order uuid", "effectivedate" "2025 01 01" }, "assets" \[ { "id" "asset uuid", "assetnumber" "sub 000001", "changetype" "updatequantity", "quantity" 150, "startdate" "2025 01 01", "enddate" "2025 12 31", "status" "draft" } ], "previews" \[ { "assetnumber" "sub 000001", "proratedamount" 2500 00, "nextinvoiceadjustment" 1000 00, "netamount" 3500 00 } ], "warnings" \[] } } error handling common change order errors error code description resolution asset not found asset number doesn't exist verify asset number format and existence invalid change type change type not supported for asset check asset type compatibility change not allowed change violates business rules review asset status and constraints insufficient permissions user lacks change permissions verify api key permissions invalid target product target product not available check product catalog availability handle change specific errors try { const result = await changeorderservice createchangeorder(changeorder); } catch (error) { if (error message includes('asset not found')) { console error('asset error subscription not found check asset number'); } else if (error message includes('change not allowed')) { console error('business rule error change not permitted for this subscription'); } else if (error message includes('invalid target product')) { console error('product error target product not available for this customer'); } } best practices change order design validate asset existence before creating change orders use appropriate change types based on business intent consider billing impact with preview invoices timing and scheduling plan effective dates considering billing cycles coordinate multiple changes for optimal customer experience respect minimum notice periods for cancellations align with customer timezone for accurate calculations business operations implement approval workflows for significant changes monitor change order patterns for customer health insights automate common changes like renewals and quantity adjustments maintain change history for customer relationship management this comprehensive guide enables you to efficiently manage subscription lifecycles through the nue change orders api, supporting all types of subscription modifications from simple quantity updates to complex product transitions