Contract Amender API
Contract Renewer API
Generate Quote Document API
Service Router
CPQ API Quickstart Guide
Disable CPQ Triggers in Apex
Salesforce CPQ Plugins
Previous Versions
Receive a CPQ contract ID in a request, and return quote data for an amendment quote.
| Required Editions |
|---|
| Available in: Salesforce CPQ Summer ’16 and later |
SBQQ.ContractManipulationAPI.ContractAmender
JSON, Apex
PATCH
Authorization: Bearer token
All of these user permissions are required.
Create on Opportunity
Without full access on Opportunity, an error results, and contract amendment fails.
Important
Read on Quote, Opportunity, and Product2
Insert and update on Quote and Opportunity
Delete on Quote and Opportunity
Name: uid
Type: String
Required: Yes
Description: 15-character case sensitive or 18-character case insensitive Salesforce Contract ID to amend.
Available in: Salesforce CPQ Winter ’21 and later
Name: AmendmentContext
Type: AmendmentContext
Required: No
Description: Context for the contract to amend.
QuoteModel
Representation of SBQQ__Quote__c data for an amendment quote
1curl "https://yourInstance.salesforce.com/services/apexrest/SBQQ/ServiceRouter?loader=SBQQ.ContractManipulationAPI.ContractAmender&uid=800R00000000X4g"
2 -H "Content-Type: application/json" -H "Authorization: Bearer token" -X PATCHAn example response body after amending a quote. 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": "a0p610000040iumAAA",
8 "Name": "Q-00880"
9 },
10 "nextKey": 5,
11 "netTotal": 300,
12 "netNonSegmentTotal": 300,
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": "a0l61000003u09UAAQ"
21 }
22 }
23 ],
24 "lineItemGroups": [ ]
25}An example response body after amending a quote. 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/a0p61000004IpR8AAK"
6 }
7 },
8 "nextKey": 4,
9 "netTotal": 0.00,
10 "lineItems": [
11 {
12 "record": {
13 "attributes": {
14 "type": "SBQQ__QuoteLine__c"
15 },
16 "SBQQ__Product__c": "01t610000033JNtAAM"
17 },
18 "productQuantityEditable": true,
19 "productHasDimensions": false,
20 "key": 3,
21 "descriptionLocked": false
22 },
23 {
24 "record": {
25 "attributes": {
26 "type": "SBQQ__QuoteLine__c"
27 },
28 "SBQQ__Product__c": "01t610000033JNUAA2",
29 "SBQQ__Product__r": {
30 "attributes": {
31 "type": "Product2",
32 "url": "/services/data/v41.0/sobjects/Product2/01t610000033JNUAA2"
33 },
34 "Id": "01t610000033JNUAA2",
35 "Name": "Product 2",
36 "ProductCode": "P2"
37 }
38 }
39 }
40 ],
41 "lineItemGroups": [
42 {
43 "record": {
44 "attributes": {
45 "type": "SBQQ__QuoteLineGroup__c",
46 "url": "/services/data/v41.0/sobjects/SBQQ__QuoteLineGroup__c/a0k61000008WIF1AAO"
47 },
48 "SBQQ__Quote__c": "a0p61000004IpR8AAK",
49 "Id": "a0k61000008WIF1AAO",
50 "SBQQ__Number__c": 1.0,
51 "SBQQ__SeparateContract__c": false,
52 "Name": "Group1"
53 },
54 "key": 2,
55 "hasMultiSegmentLines": false
56 }
57 ],
58 "customerTotal": 0.00
59}Before saving the ContractAmender example class, make sure that the CPQ model classes are added as individual Apex classes in your org.
Note
In this example, the amendment context isn’t used.
1public with sharing class ContractAmender {
2 public QuoteModel load(String contractId) {
3 String quoteJSON = SBQQ.ServiceRouter.load('SBQQ.ContractManipulationAPI.ContractAmender', contractId, null);
4 return (QuoteModel) JSON.deserialize(quoteJSON, QuoteModel.class);
5 }
6}
7
8ContractAmender amender = new ContractAmender();
9QuoteModel quote = amender.load('8001D000000AUlg'); // example id
10System.debug(quote);In this example, the amendment context is used.
1public with sharing class ContractAmenderTest {
2
3 public QuoteModel load(String contractId, String context) {
4
5 String quoteJSON = SBQQ.ServiceRouter.load('SBQQ.ContractManipulationAPI.ContractAmender', contractId, context);
6 return (QuoteModel) JSON.deserialize(quoteJSON, QuoteModel.class);
7 }
8}
9
10// Create an amendment context
11private with sharing class AmendmentContextTest {
12 public Boolean returnOnlyQuoteId;
13}
14
15AmendmentContextTest context = new AmendmentContextTest();
16context.returnOnlyQuoteId = true;
17
18// Invoke the ContractAmender API
19String contextJson = JSON.serialize(context);
20ContractAmenderTest amender = new ContractAmenderTest();
21QuoteModel quote = amender.load('CONTRACT_ID', contextJson);Example response body for returnOnlyQuoteId = true:
1{"attributes":{"type":"SBQQ__Quote__c","url":"/services/data/v50.0/sobjects/SBQQ__Quote__c/12345"},"Id":"12345"}