Composite API - An Overview

The composite API allows you to combine up to five API calls in a single request consuming just one or two credits per composite call. This API reduces the round-trip time and allows you to execute the APIs in a single database transaction, if needed.

What is Round-trip time (RTT) and how does this API reduce it?
The time taken for the request to reach the server and render a response is called the Round-trip time.
Since you club all the requests in a composite API, round-trip time is saved. Should one or more of the sub-requests fail, you can choose to rollback (revert all the changes) the entire transaction.

The keys "rollback_on_fail" and "concurrent_execution"

  • rollback_on_fail: This boolean key represents whether you want to rollback the composite request when one or more sub-requests fail.

  • concurrent_execution: This boolean key represents whether you want to process all the independent sub-requests in parallel. When "rollback_on_fail" is true, this key should hold the value false.

Let us discuss the two scenarios in which this API is at its best.

  1. Sub-requests are not executed under the same transaction
    • 1.a. Independent APIs (requests are served concurrently, rollback_on_fail:false, concurrent_exec:true))
      Consider that you want to fetch the metadata of the Leads module, its layouts, fields, and custom views. Instead of making four individual API calls and losing four credits, you can use the composite API for just one credit. On our server side, we will process the API calls in parallel. Here is the sample request.

      {
          "__composite_requests": [
              {
                  "uri": "/crm/v3/settings/modules/Leads",
                  "method": "GET"
              },
              {
                  "uri": "/crm/v3/settings/fields",
                  "method": "GET",
                  "params": {
                      "module": "Leads"
                  }
              },
              {
                  "uri": "/crm/v3/settings/layouts",
                  "method": "GET",
                  "params": {
                      "module": "Leads"
                  }
              },
              {
                  "uri": "/crm/v3/settings/custom_views",
                  "method": "GET",
                  "params": {
                      "module": "Leads"
                  }
              }
          ]
      }
      
    • 1.b. With dependent sub-requests (requests are served sequentially, rollback_on_fail:false, concurrent_exec:true)
      Consider a use case where you update a contact's Lead Source to Employee Referral in a sub-request. In sub-request 2, you insert a lead that triggers a workflow when the related contact's lead source is employee referral.
      In parallel execution, we cannot guarantee that sub-request 1 is served first followed by sub-request 2. So, the workflow might not be updated in sub-request 2 as the criteria will not be met before serving sub-request 1. In this case, sequential execution is the way to go. Here is how the request looks:

      {
          "concurrent_execution": false,
          "__composite_requests": [
              {
                  "uri": "/crm/v3/Contacts",
                  "method": "PUT",
                  "body": {
                      "data": [
                          {
                              "Lead_Source": "Employee_Referral",
                              "id": 111111000000106240
                          }
                      ]
                  }
              },
              {
                  "uri": "/crm/v3/Leads",
                  "method": "POST",
                  "body": {
                      "data": [
                          {
                              "Last_Name": "Boyle"
                          }
                      ]
                  }
              }
          ]
      }
      
  2. Sub Requests are executed under the same transaction (rollback_on_fail:true, concurrent_exec:false)
    This flow is useful when your custom business logic is complex and demands multiple operations in a single transaction. Consider an example where you want to close a deal, create a quote for that deal, and add a tag to that quote.
    This composite API call consumes just two credits on successful execution, while it consumes one credit when a rollback is performed. The input would look like the following.

    {
    "rollback_on_fail":true,
        "__composite_requests":[
            {
                 "uri":"/crm/v3/Deals",
                 "method":"PUT",
                 "body": {
                    "data":
                    [
                        {
                            "Stage":"Closed Won",
                            "Closing_Date":"2022-04-30",
                            "id":111111000000056144
                        }
                    ]
                 },
                 "sub_request_id":"1"
            },
             {
                 "uri":"/crm/v3/Quotes",
                 "sub_request_id":"2",
                 "method":"POST",
                 "body":{
                    "data":[
                        {
                            "Product_Details":[
                                {
                                    "product":{
                                        "id":"111111000000106008"
                                    },
                                    "quantity":1
                                 }
                            ],
                            "Subject":"Quotes1",
                            "Deal_Name":"@{1:$.data[0].details.id}"
                        }
                    ]
                }
            },
            {
                 "uri":"/crm/v3/Quotes/@{2:$.data[0].details.id}/actions/add_tags",
                 "method":"POST",
                 "params":{
                     "tag_names":"T1"
                 }
            }
        ]}}
    

Credits

rollback_on_failconcurrent_executionRollback performed?Credits consumed
truefalseNo2
truefalseYes1
falsetrueNA1
falsefalseNA1