The Salesforce Tooling API

For an internal project – the awesome Aptly Marketing Automation Toolbox – a new use case popped up. We needed to be able to automatically create Triggers for Standard as well as Custom Salesforce Objects.

For the sake of readability, I’ll refer to those as SObjects in the upcoming blog post. For such a purpose, Salesforce offers the Tooling API (please note that the Salesforce Tooling API is not available in all Salesforce editions).

Exploring the Salesforce Tooling API was quite a challenge for me as a Junior Developer. Finding out about the possibility of automatically creating pre-set, even test covered code under self-chosen and fully customizable circumstances stunned me. The concrete use case we had was that we wanted to enable some objects (configurated via a point and click UI by the non-techie salesforce user).

The very first thing to decide is whether you want to use the Tooling API with a REST or a SOAP client. Salesforce does deliver a pre-built WSDL file for SOAP, so if you want to go down that road, do not hesitate – simply navigate to your instance, head to setup, check your API section and there you have your WSDL file. Download it, then go to Apex Classes -> Create -> Create from WSDL.

However, this blog post is going to cover the usage of the Tooling API via REST. To do so, go ahead and create a Apex Class which you name in a way you desire.

Set up your class as it suits your needs. If you’ve done so, add a method to your class:


1. The trigger body is the return value of a function called „getTriggerBody()“. I recommend to do so to simply retain readability of your code. Passing the trigger body as a string would do just as fine.

2. Depending on what kind of code shall be inserted, the endpoint of the HttpRequest needs to be changed. In our case, we’re talking about triggers, so we use the trigger endpoint. For other types of code, e.g. an Apex Class, the endpoint needs to be changed. For the endpoints, just go ahead and check the Tooling API documentation for further details. However, the base URL is always the same, thus we are storing it in a variable to maintain readable code. As of today, the URL should be:

But what is the trigger supposed to do? That is completely of to you. The great thing is that the HttpRequest that we use carries the information on what to create in a JSON format. For a trigger, as it is in the example code, the specifications of the following attributes are mandatory:

  • „Name“ – the name that the trigger should have
  • „TableEnumOrId“ – the API name of the object the trigger should be attached to
  • „Body“ – the code of the trigger

All of these attributes have to be passed in a string format. Those strings can be created absolutely dynamically. Possibilities to do so are a Visualforce page with input fields, or a custom setting record, or whatever you imagine that can hold a string and is of course available in Salesforce.

With proper formatting, the string that holds the body attribute enables you to dynamically creating code. Well, on a personal note, I experienced that this kind of formatting can be really frustrating, especially when it comes to whitespaces and linebreaks. What I found out rather fast was that for some reason, too many line breaks will cause the JSON to be malformed, thus resulting in the following:


This blog post is supposed to enable everyone who reads it to easily get a grip on the Tooling API. Of course, the Tooling API can do even more than just the bit that was spotlighted. Feel free to dive in deep into the Salesforce Tooling API Developer’s Guide!

If you have further questions, do not hesitate to contact us via email

The following two tabs change content below.

Lukas Heinen

Lukas is a Junior Developer at Aptly. Since he's a qualified IT specialist, his blogposts broach the issue of everday as well as special challenges and experiences, which evolve from the usage of webbased cloud-technologies like Salesforce.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.