Developer Resources
Create Quote & Create Order Gl...
Subscription Terms, Dates & Overrides
28 min
the create quote api provides flexible control over https //docs nue io/understanding subscription term basis and proration , billing settings, and date ranges at both the quote header level and per product level this article covers term configuration, date calculation rules, per product overrides, evergreen subscriptions, and backdating term calculation rules the api supports three approaches for specifying subscription duration you provide any two of the three values, and the third is calculated automatically you provide calculated startdate + enddate term (in months) startdate + term enddate startdate + term + enddate all three validated for consistency default if only startdate is provided, the term defaults to the org's system setting (typically 12 months) end date convention end dates are inclusive — a 24 month term starting 2026 01 01 produces an end date of 2027 12 31 (start + 24 months 1 day) term dimension the ruby subscriptiontermdimension c field accepts 'month' or 'year' when set to 'year' , a term of 2 means 2 years (24 months) use case 1 standard 12 month term the most common configuration specify startdate , enddate , term=12 , and dimension='month' opportunity opp = \[select id, accountid from opportunity where accountid != null limit 1]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = '12 month standard quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionenddate c = date newinstance(2026, 12, 31), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals(12, qli ruby subscriptionterm c); // listprice x qty x term = listtotalprice // e g , $49 90 x 10 x 12 = $5,988 00 use case 2 24 month term with future start date start the subscription 3 months in the future with a 24 month term the api calculates the end date as startdate + 24 months 1 day ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); date futurestart = date today() addmonths(3); request quote = new quote( opportunityid = opp id, name = '24 month future start quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = futurestart, ruby subscriptionterm c = 24, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); // end date = startdate + 24 months 1 day (inclusive convention) date expectedend = futurestart addmonths(24) adddays( 1); system assertequals(expectedend, response data quote ruby subscriptionenddate c); system assertequals(24, response data quote ruby subscriptionterm c); use case 3 short term subscriptions (3 month and 6 month) sub annual terms work identically the pricing formula multiplies by the term listprice x qty x term = listtotalprice 3 month term ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = '3 month short term quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionterm c = 3, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals(3, qli ruby subscriptionterm c); // $49 90 x 10 x 3 = $1,497 00 6 month term ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = '6 month short term quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionterm c = 6, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals(6, qli ruby subscriptionterm c); // $49 90 x 10 x 6 = $2,994 00 use case 4 per product term overrides different products on the same quote can have different subscription terms use productinput subscriptionterm and productinput subscriptiontermdimension to override the quote level term for individual products ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'mixed term quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // product 1 override to 6 month term ruby globalapitypes productinput product1 = new ruby globalapitypes productinput(); product1 productsku = 'nue on salesforce'; product1 uom = 'user/month'; product1 quantity = 10; product1 subscriptionterm = 6; product1 subscriptiontermdimension = 'month'; // product 2 uses quote level 12 month term (no override) ruby globalapitypes productinput product2 = new ruby globalapitypes productinput(); product2 productsku = 'nue platform'; product2 uom = 'user/month'; product2 quantity = 5; product2 subscriptionterm = 12; product2 subscriptiontermdimension = 'month'; request products = new list\<ruby globalapitypes productinput>{ product1, product2 }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); // product 1 has 6 month term quotelineitem qli1 = response data lineitems\[0] quotelineitem; system assertequals(6, qli1 ruby subscriptionterm c); // product 2 has 12 month term quotelineitem qli2 = response data lineitems\[1] quotelineitem; system assertequals(12, qli2 ruby subscriptionterm c); use case 5 auto renew control the auto renewal setting per product via productinput autorenew when not specified, the product inherits the default from the product2 catalog record ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; product autorenew = true; // enable auto renewal request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals(true, qli ruby autorenew c); to explicitly disable auto renewal (overriding a catalog default) product autorenew = false; use case 6 billing period and billing timing overrides override the default billing period and timing on a per product basis the api accepts both label values (e g , 'monthly' ) and stored values (e g , 'month' ) and normalizes them automatically valid billing period values label (input) stored value monthly month quarterly quarter semi annual semi annual annual annual same as subscription term same as subscription term valid billing timing values value in advance in arrears example ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'impl service'; product uom = 'user/month'; product quantity = 10; product billingperiod = 'monthly'; // stored as 'month' product billingtiming = 'in advance'; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals('month', qli ruby billingperiod c); // normalized to stored value system assertequals('in advance', qli ruby billingtiming c); note when not specified, billing period and timing are inherited from the product2 catalog record's default values use case 7 evergreen subscriptions evergreen subscriptions have no fixed term or end date set productinput evergreen = true to create an evergreen line item enabling evergreen ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'evergreen quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue platform'; product uom = 'user/month'; product quantity = 10; product evergreen = true; // no fixed term request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); quotelineitem qli = response data lineitems\[0] quotelineitem; system assertequals(true, qli ruby evergreen c); catalog default evergreen if a product's catalog record has ruby evergreen c = true , the line item automatically inherits evergreen status without any api input to override and switch back to a fixed term ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'evergreen product'; product uom = 'user/month'; product quantity = 10; product evergreen = false; // override catalog default product subscriptionterm = 12; // now requires a fixed term product subscriptiontermdimension = 'month'; request products = new list\<ruby globalapitypes productinput>{ product }; validation evergreen conflicts setting evergreen = true together with subscriptionterm or enddate produces an invalid input error // this will fail ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue platform'; product uom = 'user/month'; product quantity = 10; product evergreen = true; product subscriptionterm = 12; // conflict! // error "cannot set subscriptionterm or enddate when evergreen is true // evergreen subscriptions have no fixed term " use case 8 renewal term use productinput renewalterm to set a custom renewal period (in months) that differs from the original subscription term when the subscription auto renews, it will use this renewal term ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; product subscriptionterm = 12; product subscriptiontermdimension = 'month'; product autorenew = true; product renewalterm = 6; // renew for 6 months instead of the original 12 request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); when renewalterm is not specified, the product inherits the ruby defaultrenewalterm c from the product2 catalog record validation renewalterm must be greater than 0 a value of 0 or negative returns product renewalterm invalid use case 9 backdated quotes the api allows start dates in the past this is useful for retroactive quotes or mid period adjustments ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'backdated quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date today() addmonths( 3), // 3 months ago ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // backdated start dates are accepted system assertequals('succeed', response status); system assertequals(date today() addmonths( 3), response data quote ruby subscriptionstartdate c); use case 10 term calculation from dates you do not need to provide all three of startdate , enddate , and term the api calculates the missing value provide start + end, term auto calculated ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'auto term quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionenddate c = date newinstance(2026, 12, 31) // ruby subscriptionterm c is not set — will be calculated ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); system assertequals(12, response data quote ruby subscriptionterm c); // auto calculated provide start + term, end date auto calculated ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'auto enddate quote', pricebook2id = stdpricebookid, ruby subscriptionstartdate c = date newinstance(2026, 1, 1), ruby subscriptionterm c = 18, ruby subscriptiontermdimension c = 'month' // ruby subscriptionenddate c is not set — will be calculated ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue on salesforce'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); // end date = jan 1 2026 + 18 months 1 day = jun 30 2027 system assertequals(date newinstance(2027, 6, 30), response data quote ruby subscriptionenddate c); key behaviors summary behavior details term dimension 'month' or 'year' — applied at both quote header and per product level one time products term is forced to 1 regardless of quote level term recurring pricing formula listprice x quantity x term = listtotalprice catalog defaults inherited billingtiming , billingperiod , autorenew , defaultrenewalterm from the product2 record per product overrides win productinput settings take precedence over quote level settings start date default if ruby subscriptionstartdate c is not provided, defaults to date today() backdated start allowed start dates in the past are accepted without error evergreen + term conflict setting evergreen = true with subscriptionterm or enddate returns invalid input zero/negative term returns product subscriptionterm invalid (per product) or quote subscriptionterm invalid (header) zero/negative renewalterm returns product renewalterm invalid
Have a question?
Get answers fast with Nue’s intelligent AI, expert support team, and a growing community of users - all here to help you succeed.
To ask a question or participate in discussions, you'll need to authenticate first.