Calculate Quote API

The Calculate Quote API calculates the prices of a CPQ quote.

Required Editions
Available in: Salesforce CPQ Summer ’16 and later

Calculate Quote API performances handles calculations similarly to the speed of asynchronous calculations in Salesforce CPQ. We do not recommend using it for processes that require instant calculation.

The Calculate Quote API doesn’t use batches when creating and calculating quotes. Performance may vary for quotes with large volumes of quote lines.

The Calculate Quote API requires callback when evaluating quote-scoped product rules.

Note

Formats

JSON, Apex

HTTP Method

PATCH

Authentication

Authorization: Bearer token

REQUEST

Parameter 1

Name: quote

Type: QuoteModel

Required: Yes

Description: Representation of SBQQ__Quote__c data. See CPQ API QuoteModel

Parameter 2

Name: callbackClass

Type: String

Required: Required for Apex Trigger

Description: This Apex class implements the CPQ CalculateCallback interface.

REST Examples 

1curl "https://YOURINSTANCE.salesforce.com/services/apexrest/SBQQ/ServiceRouter?loader=SBQQ.QuoteAPI.QuoteCalculator" -H 
2"Content-Type: application/json" -H "Authorization: Bearer token" -X PATCH -d 
3"@quoteToCalculate.json"

This request body quoteToCalculate.json file calculates a quote. The context value is a JSON formatted string.

1{"context":"{\"quote\":{\"record\":{\"attributes\":{\"type\":\"SBQQ__Quote__c\",
2\"url\":\"/services/data/v41.0/sobjects/SBQQ__Quote__c/a0p61000002NUmoAAG\"},
3\"SBQQ__PartnerDiscount__c\":null,\"SBQQ__GenerateContractedPrice__c\":null,
4\"SBQQ__QuoteProcessId__c\":\"a0m61000005NYxO\",
5\"SBQQ__NetAmount__c\":100.0,\"SBQQ__CustomerDiscount__c\":null,
6\"SBQQ__CustomerAmount__c\":100.0,\"SBQQ__PaymentTerms__c\":\"Net30\",
7\"SBQQ__RenewalUpliftRate__c\":null,\"Name\":\"Q-00822\",\"SBQQ__Type__c\":\"Quote\",
8\"SBQQ__SubscriptionTerm__c\":null,\"SBQQ__MarkupRate__c\":null,
9\"SBQQ__OrderGroupID__c\":null,\"SBQQ__DistributorDiscount__c\":null,
10\"SBQQ__OrderByQuoteLineGroup__c\":false,\"SBQQ__OrderBy__c\":null,
11\"SBQQ__PricebookId__c\":\"01s61000000LI67AAG\",\"SBQQ__EndDate__c\":null,
12\"SBQQ__Account__c\":null,\"SBQQ__StartDate__c\":null,
13\"SBQQ__FirstSegmentTermEndDate__c\":null,\"SBQQ__BillingFrequency__c\":null,
14\"SBQQ__LineItemsGrouped__c\":false,\"SBQQ__ExpirationDate__c\":null,
15\"SBQQ__Primary__c\":false,\"SBQQ__LineItemCount__c\":1.0,\"SBQQ__MasterContract__c\":null,
16\"SBQQ__EditLinesFieldSetName__c\":null,
17\"Id\":\"a0p61000002NUmoAAG\",\"SBQQ__Unopened__c\":false,\"SBQQ__RenewalTerm__c\":null},
18\"nextKey\":2,\"netTotal\":100.00,
19\"netNonSegmentTotal\":100.0000,\"lineItems\":[{\"upliftable\":false,
20\"targetCustomerTotal\":null,\"targetCustomerAmount\":null,
21\"record\":{\"attributes\":{\"type\":\"SBQQ__QuoteLine__c\",
22\"url\":\"/services/data/v41.0/sobjects/SBQQ__QuoteLine__c/a0l610000061yHpAAI\"},
23\"SBQQ__CarryoverLine__c\":false,\"SBQQ__TermDiscountTier__c\":null,
24\"SBQQ__VolumeDiscount__c\":null,\"SBQQ__BillingType__c\":null,
25\"SBQQ__Discount__c\":null,\"SBQQ__ListPrice__c\":100.0,\"SBQQ__Existing__c\":false,
26\"SBQQ__ProductName__c\":\"Product1\",\"SBQQ__SegmentIndex__c\":null,
27\"SBQQ__DiscountTier__c\":null,\"SBQQ__SBCustomLevel__c\":null,\"SBQQ__ComponentTotal__c\":null,
28\"SBQQ__RenewedSubscription__c\":null,
29\"SBQQ__SubscriptionTargetPrice__c\":null,\"SBQQ__AllowAssetRefund__c\":false,
30\"SBQQ__Optional__c\":false,\"SBQQ__PriorQuantity__c\":null,
31\"SBQQ__Source__c\":null,\"SBQQ__Quote__c\":\"a0p61000002NUmoAAG\",\"SBQQ__SBCustomEndDate__c\":null,
32\"SBQQ__ProratedListPrice__c\":100.0,\"SBQQ__ChargeType__c\":null,
33\"SBQQ__UpliftAmount__c\":0.0,\"SBQQ__ComponentSubscriptionScope__c\":null,
34\"SBQQ__OptionLevel__c\":null,\"SBQQ__NetPrice__c\":100.0,\"SBQQ__SBCustomCity__c\":null,
35\"Id\":\"a0l610000061yHpAAI\",\"SBQQ__OriginalQuoteLineId__c\":null,
36\"SBQQ__RegularPrice__c\":100.0,\"SBQQ__EffectiveQuantity__c\":1.0,\"SBQQ__Quantity__c\":1.0,
37\"SBQQ__TaxCode__c\":null,\"SBQQ__sbCustom_Number1__c\":null,\"SBQQ__ContractedPrice__c\":null,
38\"SBQQ__CostEditable__c\":false,\"SBQQ__Dimension__c\":null,
39\"SBQQ__DynamicOptionId__c\":null,\"SBQQ__SBCustomSupport__c\":null,
40\"SBQQ__PreviousSegmentUplift__c\":null,\"SBQQ__EndDate__c\":null,\"SBQQ__PreviousSegmentPrice__c\":null,
41\"SBQQ__UpgradedSubscription__c\":null,\"SBQQ__SpecialPriceType__c\":null,
42\"SBQQ__SegmentKey__c\":null,\"SBQQ__OptionDiscount__c\":null,\"SBQQ__RequiredBy__c\":null,
43\"SBQQ__UpgradedAsset__c\":null,\"SBQQ__Bundled__c\":false,\"SBQQ__SBCustomColor__c\":null,
44\"SBQQ__OptionType__c\":null,\"SBQQ__Number__c\":1.0,\"SBQQ__SubscriptionPercent__c\":null,
45\"SBQQ__ComponentListTotal__c\":null,\"SBQQ__TermDiscountSchedule__c\":null,
46\"SBQQ__Taxable__c\":false,\"SBQQ__Description__c\":null,\"SBQQ__ProductCode__c\":\"P1\",
47\"SBQQ__OriginalPrice__c\":100.0,\"SBQQ__GenerateContractedPrice__c\":null,
48\"SBQQ__NetTotal__c\":100.0,\"SBQQ__UnitCost__c\":null,\"SBQQ__SubscriptionCategory__c\":null,
49\"SBQQ__Hidden__c\":false,\"SBQQ__NonDiscountable__c\":false,\"SBQQ__Markup__c\":0.0,\"SBQQ__RenewedAsset__c\":null,
50\"SBQQ__GrossProfit__c\":null,\"SBQQ__MinimumPrice__c\":null,
51\"SBQQ__BundledQuantity__c\":null,\"SBQQ__BatchQuantity__c\":null,
52\"SBQQ__ProrateMultiplier__c\":1.0,\"SBQQ__CustomerPrice__c\":100.0,\"SBQQ__SubscriptionTerm__c\":null,
53\"SBQQ__MarkupRate__c\":null,\"SBQQ__DistributorDiscount__c\":null,
54\"SBQQ__DefaultSubscriptionTerm__c\":null,\"SBQQ__PriceEditable__c\":false,
55\"SBQQ__ProratedPrice__c\":100.0,
56\"SBQQ__ComponentUpliftedByPackage__c\":false,\"SBQQ__StartDate__c\":null,
57\"SBQQ__NonPartnerDiscountable__c\":false,\"SBQQ__BlockPrice__c\":null,\"SBQQ__MaximumPrice__c\":null,
58\"SBQQ__SubscriptionPricing__c\":null,\"SBQQ__AdditionalDiscount__c\":0.0,\"SBQQ__Favorite__c\":null,
59\"SBQQ__ProductOption__c\":null,\"SBQQ__OptionDiscountAmount__c\":null,
60\"SBQQ__TermDiscount__c\":null,\"SBQQ__MarkupAmount__c\":null,\"SBQQ__PartnerDiscount__c\":null,
61\"SBQQ__ComponentDiscountedByPackage__c\":false,\"SBQQ__Renewal__c\":false,
62\"SBQQ__CompoundDiscountRate__c\":null,\"SBQQ__UpgradedQuantity__c\":null,
63\"SBQQ__AdditionalDiscountAmount__c\":null,\"SBQQ__Cost__c\":null,
64\"SBQQ__PackageProductDescription__c\":null,\"SBQQ__PartnerPrice__c\":100.0,\"SBQQ__DiscountSchedule__c\":null,
65\"SBQQ__ComponentCost__c\":null,\"SBQQ__SubscribedAssetIds__c\":null,
66\"SBQQ__SubscriptionScope__c\":\"Quote\",\"SBQQ__Product__r\":{\"attributes\":
67{\"type\":\"Product2\",\"url\":\"/services/data/v41.0/sobjects/Product2/01t610000033JNPAA2\"},
68\"SBQQ__ExternallyConfigurable__c\":false,\"SBQQ__CostEditable__c\":false,\
69"SBQQ__QuantityEditable__c\":true,\"SBQQ__Hidden__c\":false,\"SBQQ__ExcludeFromOpportunity__c\":false,
70\"SBQQ__NonDiscountable__c\":false,\"Name\":\"Product1\",\"PricebookEntries\":
71{\"totalSize\":1,\"done\":true,\"records\":[{\"attributes\":{\"type\":\"PricebookEntry\",
72\"url\":\"/services/data/v41.0/sobjects/PricebookEntry/01u610000055KTeAAM\"},\
73"UnitPrice\":100.0,\"Product2Id\":\"01t610000033JNPAA2\",\"IsActive\":true,
74\"Pricebook2Id\":\"01s61000000LI67AAG\",\"Id\":\"01u610000055KTeAAM\"}]},
75\"SBQQ__AssetConversion__c\":\"Oneperquoteline\",\"SBQQ__IncludeInMaintenance__c\":false,
76\"SBQQ__PriceEditable__c\":false,\"SBQQ__ReconfigurationDisabled__c\":false,
77\"SBQQ__DescriptionLocked__c\":false,\"SBQQ__NewQuoteGroup__c\":false,\"SBQQ__Optional__c\":false,
78\"SBQQ__ExcludeFromMaintenance__c\":false,
79\"SBQQ__AssetAmendmentBehavior__c\":\"Default\",\"ProductCode\":\"P1\",\"SBQQ__OptionSelectionMethod__c\":\"Click\",
80\"SBQQ__SubscriptionType__c\":\"Renewable\",\"SBQQ__SubscriptionBase__c\":
81\"List\",\"SBQQ__CustomConfigurationRequired__c\":false,\"SBQQ__NonPartnerDiscountable__c\":false,
82\"SBQQ__DefaultQuantity__c\":1.0,\"SBQQ__PricingMethodEditable__c\":false,\"SBQQ__BlockPricingField__c\
83":\"Quantity\",\"SBQQ__HasConfigurationAttributes__c\":false,\"SBQQ__Taxable__c\":false,
84\"SBQQ__PricingMethod__c\":\"List\",\"Id\":\"01t610000033JNPAA2\"},\"SBQQ__SubscriptionBase__c\
85":\"List\",\"SBQQ__BillingFrequency__c\":null,\"SBQQ__OriginalUnitCost__c\":null,
86\"SBQQ__sbcustom_TwinField__c\":null,\"SBQQ__Bundle__c\":false,\"SBQQ__Product__c\":\
87"01t610000033JNPAA2\",\"SBQQ__SpecialPrice__c\":100.0,\"SBQQ__PricingMethodEditable__c\":false,
88\"SBQQ__Uplift__c\":0.0,\"SBQQ__PackageProductCode__c\":null,\"SBQQ__PricingMethod__c\":\"List\",
89\"SBQQ__SegmentLabel__c\":null,\"SBQQ__AdditionalQuantity__c\":null,
90\"SBQQ__DiscountScheduleType__c\":null},\"reconfigurationDisabled\":false,\"productQuantityScale\"
91:null,\"productQuantityEditable\":true,\"productHasDimensions\":false,
92\"parentItemKey\":null,\"parentGroupKey\":null,\"key\":2,\"dimensionType\":null,\"descriptionLocked\":false,
93\"configurationType\":null,\"configurationEvent\":null,
94\"amountDiscountProrated\":null}],\"lineItemGroups\":[],\"customerTotal\":100.00,\"channelDiscountsOffList\":false,
95\"applyPartnerDiscountFirst\":false,\"applyAdditionalDiscountLast\":false}}"}

An example response body after successfully calculating a product. The actual response is a JSON formatted string.

1{    
2  "record": {        
3    "attributes": {            
4      "type": "SBQQ__Quote__c",             
5      "url": "/services/data/v41.0/sobjects/SBQQ__Quote__c/a0p610000040iumAAA"        
6    }, 
7    "Id": "a0p61000002NUmoAAG",         
8    "Name": "Q-00822"    
9  }, 
10  "nextKey": 2,     
11  "netTotal": 200,     
12  "netNonSegmentTotal": 200, 
13    "lineItems": [        
14      {            
15        "record": {
16          "attributes": {                    
17            "type": "SBQQ__QuoteLine__c", 
18            "url": "/services/data/v41.0/sobjects/SBQQ__QuoteLine__c/a0l61000003u09UAAQ"
19          },                 
20          "Id": "a0l610000061yHpAAI",
21          "SBQQ__NetTotal__c": 200            
22        }        
23      }    
24   "lineItemGroups": []
25}

Apex Examples 

When you execute the Calculate API with an Apex trigger, you also need to create a quote calculator callback class. This class must implement the CPQ CalculateCallback interface to save the quote after calculating it in the background.

1global with sharing class MyCallback implements SBQQ.CalculateCallback {
2  global void callback(String quoteJSON){
3    SBQQ.ServiceRouter.save('SBQQ.QuoteAPI.QuoteSaver', quoteJSON);       
4  }
5}

Before saving the QuoteCalculator example class, make sure that the CPQ model classes are added as individual Apex classes in your org.

1public with sharing class QuoteCalculator {     
2
3  public void calculate(QuoteModel quote, String callbackClass) {
4    QuoteCalculatorContext ctx = new QuoteCalculatorContext(quote, callbackClass);
5    SBQQ.ServiceRouter.load('SBQQ.QuoteAPI.QuoteCalculator', null, JSON.serialize(ctx));    
6  }    
7
8  private class QuoteCalculatorContext {        
9    private QuoteModel quote;             //The quote and callbackClass properties are called in the API code by the exact names seen here.
10    private String callbackClass;         //Altering these property names will cause calculator API calls to fail.
11
12    private QuoteCalculatorContext(QuoteModel quote, String callbackClass) {
13      this.quote = quote;            
14      this.callbackClass = callbackClass;        
15    }
16  } 
17}

For an example of the QuoteCalculator class, run the following code in anonymous Apex.

1QuoteModel quoteModel; // Use Read or Add Products APIs to obtain a QuoteModel
2
3quoteModel.lineItems[0].record.SBQQ__Quantity__c = 2;
4QuoteCalculator calculator = new QuoteCalculator();
5calculator.calculate(quoteModel, 'MyCallback');