Configuration Loader API
Configuration Load Rule Executor API
Configuration Validator API
Generate Quote Document API
Service Router
CPQ API Quickstart Guide
Disable CPQ Triggers in Apex
Salesforce CPQ Plugins
Previous Versions
The Configuration Validator API runs selection, validation, and alert product rules and configurator-scoped price rules against the input configuration model and returns an updated configuration model.
| Required Editions |
|---|
| Available in: Salesforce CPQ Spring ’17 and later |
JSON, Apex
PATCH
Authorization: Bearer token
REQUEST
| Name | Type | Description | |
|---|---|---|---|
| uid | String | Required | ID of the Product2 record |
| quote | QuoteModel | Required | Corresponds directly to SBQQ__Quote__c. |
| configuration | ConfigurationModel | Required | The product’s configuration data. |
| event | String | Required | Event type of product and price rules to run. Options are “Load”, “Save”, “Edit”, and “Always”. |
| upgradedAssetId | String | Optional | Asset ID when upgrading a bundle. |
RESPONSE
| Type | Description | ||
|---|---|---|---|
| ConfigurationModel | The product’s configuration data. This is the same Configuration Model that was passed in the request, but the data will be changed based on Product Actions from Product and Price Rules that ran. See CPQ Models. |
1curl "https://YOURINSTANCE.salesforce.com/services/apexrest/SBQQ/ServiceRouter?loader=SBQQ.ConfigAPI.ConfigurationValidator&uid=a0x5C000000G1CV \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer YOURAUTHORIZATIONTOKEN" \
4 -X PATCH \
5 -d "@configValidatorContext.json”The example request body configValidatorContext.json file for running product and price rules. This example context value is a JSON-formatted string of the quote model, configuration model, and event type.
1{"context":"{\"quote\":{\"record\":{\"attributes\":{\"type\":\"SBQQ__Quote__c\"},
2 \"Account__c\":\"0012F00000ayBPwQAM\",
3 \"Id\":\"a0z2F000000xGLpQAM\",
4 \"PricebookId__c\":\"01s2F0000011yApQAI\",
5 \"CurrencyIsoCode\":\"USD\"}},
6 \"configuration\":{\"validationMessages\":[],
7 \"priceEditable\":false,
8 \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
9 \"optionConfigurations\":[{\"validationMessages\":[],
10 \"priceEditable\":false,
11 \"optionId\":\"a0o2F000001Yi4JQAS\",
12 \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\",
13 \"url\":\"\/services\/data\/v48.0\/sobjects\/ProductOption__c\/a0o2F000001Yi4JQAS\"},
14 \"ConfiguredSKU__c\":\"01t2F000004XoPLQA0\",
15 \"Id\":\"a0o2F000001Yi4JQAS\",
16 \"OwnerId\":\"0056100000148O6AAI\",
17 \"IsDeleted\":false,
18 \"CurrencyIsoCode\":\"USD\",
19 \"SystemModstamp\":\"2020-03-10T20:47:39.000+0000\",
20 \"AppliedImmediately__c\":false,
21 \"Bundled__c\":false,
22 \"DiscountedByPackage__c\":false,
23 \"Number__c\":1,
24 \"OptionalSKU__c\":\"01t4M000003ru2PQAQ\",
25 \"PriceEditable__c\":\"No\",
26 \"ProductConfigurationType__c\":\"Allowed\",
27 \"ProductName__c\":\"Nested Option Product #1\",
28 \"QuantityEditable__c\":true,
29 \"Quantity__c\":1,
30 \"Required__c\":false,
31 \"Selected__c\":true,
32 \"System__c\":false,
33 \"Type__c\":\"Component\",
34 \"UpliftedByPackage__c\":false,
35 \"CanOrderSeparately__c\":false},
36 \"optionConfigurations\":[],
37 \"isUpgrade\":false,
38 \"isDynamicOption\":false,
39 \"configuredProductId\":\"01t2F000004XoPLQA0\",
40 \"configured\":false,
41 \"configurationEntered\":false,
42 \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
43 \"changedByProductActions\":false}],
44 \"isUpgrade\":false,
45 \"isDynamicOption\":false,
46 \"configuredProductId\":\"01t2F000004XoPLQA0\",
47 \"configured\":false,
48 \"configurationEntered\":false,
49 \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
50 \"changedByProductActions\":false},
51 \"event\":\"Edit\"}"}Example response body returning product configuration data. The actual response is a JSON formatted string.
1{
2 "validationMessages": ["Incorrect quantity for Product A"],
3 "priceEditable": false,
4 "optionId": null,
5 "optionData": {
6 "attributes": {
7 "type": "SBQQ_ProductOption_c"
8 }
9 },
10 "optionConfigurations": [],
11 "listPrice": null,
12 "isUpgrade": false,
13 "isDynamicOption": false,
14 "inheritedConfigurationData": null,
15 "hiddenOptionIds": null,
16 "dynamicOptionKey": null,
17 "disabledOptionIds": null,
18 "configuredProductId": "01t3D000005Th8oQAC",
19 "configured": false,
20 "configurationData": {
21 "attributes": {
22 "type": "SBQQ_ProductOption_c"
23 },
24 "SBQQ_UnitPrice_c": null
25 },
26 "changedByProductActions": false
27}Before saving the ConfigValidator example class, make sure that the CPQ Modelsclasses are added as individual Apex classes in your org.
1public with sharing class ConfigValidator {
2 public ConfigurationModel load(
3 Id productId,
4 QuoteModel quote,
5 ConfigurationModel configuration,
6 String event,
7 String upgradedAssetId) {
8
9 ValidatorContext ctx = new ValidatorContext(
10 quote,
11 configuration,
12 event,
13 upgradedAssetId);
14 String configJSON = SBQQ.ServiceRouter.load('SBQQ.ConfigAPI.ConfigurationValidator', productId, JSON.serialize(ctx));
15 return (ConfigurationModel) JSON.deserialize(configJSON, ConfigurationModel.class);
16 }
17
18 private class ValidatorContext {
19 private QuoteModel quote;
20 private ConfigurationModel configuration;
21 private String event;
22 private String upgradedAssetId;
23
24 public ValidatorContext(
25 QuoteModel quote,
26 ConfigurationModel configuration,
27 String event,
28 String upgradedAssetId) {
29
30 this.quote = quote;
31 this.configuration = configuration;
32 this.event = event;
33 this.upgradedAssetId = upgradedAssetId;
34 }
35 }
36}To demonstrate usage of the ConfigValidator class, run the following code in anonymous Apex.
1QuoteModel quote; //Use Read, Add Products, or Calculate APIs to obtain a QuoteModel
2 ProductModel product; //Use Read Product or Configuration Loader API to obtain a ProductModel
3
4 ConfigValidator validator = new ConfigValidator();
5 ConfigurationModel config = validator.load('01t2F000004XoPLQA0', quote, product.configuration, 'Edit', null);
6 System.debug(config);