REST Resource Examples

Robust examples using REST resources in the Tooling API.

Example Setup

The following examples use Apex to execute REST requests, but you can use any standard REST tool to access the Tooling API.

The examples in this guide use a production login URL with MyDomainName in place of the org’s My Domain name. The format for sandbox login URLs differs. To use these examples, update the login URL. You can find the My Domain name and My Domain login URL for your org on the My Domain page in Setup.

Note

First, set up the connection to your org and the HTTP request type:
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
At the end of each request, add the following code to send the request and retrieve the body of the response:
Http h = new Http();
HttpResponse res = h.send(req);
system.debug(res.getBody());

Retrieve a Description

To get a description of all available objects in Tooling API:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/');
req.setMethod('GET');
To get a description of a specific Tooling API object, for example, TraceFlag:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
TraceFlag/');
req.setMethod('GET');
To get a description of all metadata for a specific Tooling API object, for example, TraceFlag:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
TraceFlag/describe/');
req.setMethod('GET');

Manipulate Objects by ID

To create a new Tooling API object, for example, MetadataContainer:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
MetadataContainer/');
req.setBody('{"Name":"TestContainer"}');
req.setMethod('POST');

Use the ID from this call in the rest of the examples.

Tip

To retrieve a Tooling API object by ID, for example, MetadataContainer:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
MetadataContainer/ + containerID + '/'); 
req.setMethod('GET');
To update a Tooling API object by ID, for example, MetadataContainer:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
MetadataContainer/ + containerID + '/');
req.setBody('{"Name":"NewlyNamedContainer"}');
req.setMethod('PATCH');
To query a Tooling API object by ID, for example, MetadataContainer:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/query/?q=
Select+id,Name+from+MetadataContainer+Where+ID=\'' + containerID +  '\'');
req.setMethod('GET');

Query Within MetadataContainer

To query an object within a MetadataContainer:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/query/?q=
Select+id,Body,LastSyncDate,Metadata+from+ApexClassMember+Where+MetadataContainerID=\' 
+ containerID +  '\'');
req.setMethod('GET');

Check Deployment Status

To check on the status of a deployment, using ContainerAsyncRequest:
req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/sobjects/
ContainerAsyncRequest/' + requestID + '/');
req.setMethod('GET');

Execute Anonymous Apex

To execute anonymous Apex:

req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/executeAnonymous/?
anonymousBody=System.debug('Test')%3B');
req.setMethod('GET');

Retrieve Apex

To retrieve your Apex classes and triggers, and the global Apex classes and triggers from your installed managed packages:

req.setEndpoint('https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/apexManifest');
req.setMethod('GET');

Execute Apex Unit Tests

To execute Apex unit tests, use the runTestsSynchronous or runTestsAsynchronous resource. This example illustrates how to POST to the runTestsSynchronous resource using JavaScript. The comment blocks show which objects these calls return.

var xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://MyDomainName.my.salesforce.com/services/data/v64.0/tooling/runTestsSynchronous/", true)

// SESSION_ID is the session ID
xhttp.setRequestHeader("Authorization", "OAuth <SESSION_ID>")
xhttp.setRequestHeader('Accept', "application/json");

// testObject should include a list of object(s) with the classId and list of
//     desired test methods for the desired classes to be tested
testObject = {tests: [{classId: "N0tARealClassId", testMethods: ["testMethod1", "testMethod2"]}]}
requestObject = json.stringify(testObject);
response = xhttp.send(requestObject)
response = JSON.parse(response)

/*
{
  "successes": [
    {
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod1",
      "id": "N0tARealTestId1",
      "time": 1167,
      "seeAllData": false
    },
    {
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod2",
      "id": "N0tARealTestId2",
      "time": 47,
      "seeAllData": false
    }
  ],
  "failures": [
    {
      "type": "Class",
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod3",
      "message": "System.AssertException: Assertion Failed",
      "stackTrace": "Class.MyTestClass.testMethod3: line 13, column 1",
      "id": "01pxx0000000JTpAAM",
      "seeAllData": false,
      "time": 27,
      "packageName": "MyTestClass"
    },
    {
      "type": "Class",
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod4",
      "message": "System.AssertException: Assertion Failed",
      "stackTrace": "Class.MyTestClass.testMethod4: line 17, column 1",
      "id": "01pxx0000000JTpAAM",
      "seeAllData": false,
      "time": 32,
      "packageName": "MyTestClass"
    }
  ],
  "totalTime": 143,
  "apexLogId": "07Lxx0000000A9NEAU",
  "numFailures": 2,
  "codeCoverage": [
    
  ],
  "codeCoverageWarnings": [
    
  ],
  "numTestsRun": 4
}
*/

// Check how many tests ran
response["numTestRun"] === 4
// Check how many tests passed
response["successes"].length === 2

// Return a list of objects that correspond to the tests that passed
response["successes"]
/*
[
    {
      "id": "N0tARealTestId1",
      "methodName": "testMethod1",
      "name": "MyTestClass",
      "namespace": null,
      "seeAllData": false,
      "time": 1167
    }
  ]
*/

// Access the first object in the list
response["successes"][0]["name"] === "MyTestClass"
response["successes"][0]["methodName"] === "testMethod1"
// This ID refers to the classId
response["successes"][0]["id"] === "MyTestClass"
response["successes"][0]["time"] === 1167 // milliseconds

response["failures"]
/*
	{
      "type": "Class",
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod3",
      "message": "System.AssertException: Assertion Failed",
      "stackTrace": "Class.MyTestClass.testMethod3: line 13, column 1",
      "id": "01pxx0000000JTpAAM",
      "seeAllData": false,
      "time": 27,
      "packageName": "MyTestClass"
    },
    {
      "type": "Class",
      "namespace": null,
      "name": "MyTestClass",
      "methodName": "testMethod4",
      "message": "System.AssertException: Assertion Failed",
      "stackTrace": "Class.MyTestClass.testMethod4: line 17, column 1",
      "id": "01pxx0000000JTpAAM",
      "seeAllData": false,
      "time": 32,
      "packageName": "MyTestClass"
    }
*/

response["failures"][0]["name"] === "MyTestClass"
response["failures"][0]["methodName"] === "testMethod3"
response["failures"][0]["message"] === "System.AssertException: Assertion Failed"
response["failures"][0]["stackTrace"] === "Class.MyTestClass.testMethod3: line 13, column 1"
response["failures"][0]["time"] === 27