This post assumes you have a decent knowledge of both SSJS and a basic knowledge of SFMC APIs. If you need some background on SSJS, I highly recommend my SSJS series SFMC Server-Side JavaScript to get a strong background on the language and the possibilities it opens. If you need more info on API, I would check out the official docs or my article here on API setup in POSTman as well as REST API Methods in SSJS. There are also many resources on both in various YouTube or blogs that you can google to find more information.

SSJS API Functions

There are quite a few different functions that you can use in SSJS to make API calls. The capabilities, ease of use and performance of these vary – meaning there is no single silver bullet preferred function to do API calls. The context is a huge factor on which function to use, and we will get into that – but before we dive in, let’s take a look at what the functions are:

  • Platform API functions
  • Core Object Functions
  • WSProxy
  • HTTP.Get
  • HTTP.Post
  • Platform.Function.HTTPGet
  • Platform.Function.HTTPPost
  • Script.Util.HttpRequest
  • Script.Util.HttpGet

As you can see, there are a lot of options, and some even have more options or functions within them. You can also see there are some cases where there seems to be an overlap of capabilities and functionality. Now that we know what the options are, let’s start to take a dive into each starting with the Platform API functions.

Platform API Functions

This was one of the original ways for you to interact with the SFMC SOAP API. It is very similar to the AMPscript version of API functions, but as SSJS can use objects and arrays, it is actually quite a bit more archaic than these functions. This is because despite the native ability to use Objects and Arrays, you need to use these functions to create them instead of just using the native functionality. This is another example of the attempt for Platform SSJS to mirror the capabilities of AMPscript instead of using more native Javascript based language.

Honestly, I am not going to spend a lot of time on this as not only is it a bit convaluted, as I was talking about above, but it also is replaced very effectively by WSProxy (more details on WSProxy later in the article). WSProxy not only takes advantage of the native JS capabilities, but also is much more performant.

The Platform API functions consist of a few different functions. See below list:

AddObjectArrayItem

This item will create an object (name/value pair) to an array. This is mostly used for things like filters and similar array items that require multiple objects included.

Example:

 Platform.Function.AddObjectArrayItem(sfp,"Properties","Name")

CreateObject

This function will create an API Object that is used as a more top level holder of information. Usual usages of this is to create the API level Object (e.g. RetrieveRequest) of for creating FilterParts. This essentially creates an empty object that then needs to be filled.

Example:

var newObject = Platform.Function.CreateObject("RetrieveRequest");

Invoke{{Method}}

This is the function that invokes the appropriate method/soap action that you need to do to interact with the API object you are using. Each one has different properites and requirements that are needed or can be utilized – but in general they are used in the same way where appropriate.

List of Methods:

  • Configure
  • Create
  • InvokeDelete
  • InvokeExecute
  • InvokeExtract
  • InvokePerform
  • InvokeRetrieve
  • InvokeSchedule
  • InvokeUpdate

Each of these is called in almost identical ways – just with different properties etc.

Example:

var autoRes = Platform.Function.InvokeRetrieve(rr, status);

SetObjectProperty

Some of the API objects created require certain properties set in order to be able to function correctly. This function will set those properties inside of the correlating object.

Platform.Function.SetObjectProperty(rr, "ObjectType", "Automation");

Example of a full Platform API function call

Below is a fully fleshed out example of the above API functions – using InvokeRetrieve as the method and Automation as the SOAP API Object. This should give you a good feel for how these functions work together.

<script runat="server">

Platform.Load("Core","1.1.1");

var autoKey = "autoKey"

var rr = Platform.Function.CreateObject("RetrieveRequest");
Platform.Function.SetObjectProperty(rr, "ObjectType", "Automation");
Platform.Function.AddObjectArrayItem(rr, "Properties", "ProgramID");
Platform.Function.AddObjectArrayItem(rr, "Properties", "CustomerKey");
Platform.Function.AddObjectArrayItem(rr, "Properties", "Status");

var sfp = Platform.Function.CreateObject("SimpleFilterPart");
Platform.Function.SetObjectProperty(sfp, "Property", "CustomerKey");
Platform.Function.SetObjectProperty(sfp, "SimpleOperator", "equals");
Platform.Function.AddObjectArrayItem(sfp, "Value", autoKey);

Platform.Function.SetObjectProperty(rr, "Filter", sfp);

var status = [0,0,0];
var autoRes = Platform.Function.InvokeRetrieve(rr, status);
</script>

Ok, now let’s move on to something that is a bit more useful. Now, don’t get your hopes up as this one has a couple less then stellar selling points too – but lets discuss the Core Object Functions next!

Core Object Functions

You will notice that no where anywhere is anything listed as ‘Core Object Functions’. That is correct, I kinda made up that terminology. You see, there are a ton of Core library functions, but we are just concentrating on a few that utilize SOAP API Objects without letting you know they are using SOAP API Objects. This is why I am calling them ‘Object Functions’. Below is a listing of each of these function groups:

  • Account
  • AccountUser
  • Content Area
  • Data Extension
  • Delivery Profile
  • Email
  • Events
  • Filter Definition
  • Folder
  • List
  • Portfolio
  • Query Definition
  • Recipient
  • Send Classification
  • Send
  • Sender Profile
  • Subscriber
  • Template
  • Triggered Send

As you can see, this is a ton of different function groups that are used. The bad part though, is that as these functions are using the SOAP API, they only affect Classic Content stuff, so some of them, although still active, are completely useless or broken. For instance, the Send object, Template object and Email object are all based in Classic Content and with that being sunset and no longer used, they are useless functions.

Just because some of these are not usable anymore does not mean that these functions are not useful. For instance, using the Triggered Send group to pause, republish and restart a Triggered Send Definition with a total of around 4 lines of code is insanely useful.

As a note, to utilize the Core functions, you will need to load in the Core library inside your script.

Load the Core library:

Platform.Load("Core","1.1.1");

Full Example of a Core function being used:

var tsd = TriggeredSend.Init("myTSD");
var pause = tsd.Pause();
var publish = tsd.Publish();
var start = tsd.Start()

One thing to note on these is that they are not always the most performant of functions and although many are very simplistic and easy to utilize, they are also restricted and not as customizable as custom SOAP API calls or WSProxy. This is one of those that if you need something quick without a lot of custom properties, then the Core Functions could be a perfect fit for you with their low code usage. But if you are concerned with performance and have custom needs that are not built in, then you will want to explore other options. Also, as with most things, the error messages for these Core functions are pretty awful. Most, if they don’t just toss an error, will just output ‘Error’. Thanks….that is SO helpful…

Now we will move on to one of the greatest new developer capabilities that Marketing Cloud has introduced in many years – WSProxy.

WSProxy

This is one of the last API capabilities that is focused solely on the SOAP API. WSProxy is THE capability to use when you want to use a SOAP API call inside of SFMC. It is by far the fastest and most performant option as well as by utilizing the native JS capabilities, one of the easiest to pick up and use. This capability greatly cuts down the amount of code that is needed as well (in comparison to the API Functions) which makes reading and maintaining the scripts much easier.

WSProxy essentially creates a middle location that takes what you send in and creates and interacts with the SOAP API and then translate that and sends it back to you. It is a great thing…but it is limited to only the SOAP API currently. There was talk of a RESTProxy being created and there was much headway made, but unfortunately the person that was working on it no longer works at Salesforce, so it is entirely likely that it will be scrapped and never see the light of day.

WSProxy is direct SSJS interaction with the SOAP API, where the API Functions and even Core are essentially wrappers around AMPscript functions. This reduces the overhead and processing required, making it much more performant. To start using WSProxy, similar to many Core functions, you need to initialize/create the wrapper object.

var prox = new Script.Util.WSProxy();

This then opens you up to utilizing the many methods and objects available inside of the SOAP API. Although not every method is available, the vast majority are:

  • Create
  • Update
  • Delete
  • Retrieve
  • Perform
  • Configure
  • Execute
  • Describe

With a simple call, you can get a JSON returned with all the information you need, whether its data from a retrieve or validation information from an update or create. Below is an example of a fully built WSProxy call:

  var prox = new Script.Util.WSProxy();

  /* Set ClientID */
  //prox.setClientId({ "ID": mid }); //Impersonates the BU

  var cols = ["Name","Status"];
  var filter = {
      Property: "Status",
      SimpleOperator: "IN",
      Value: {-1,0,1,2,3,4,5,6,7,8}
  };
  var res = prox.retrieve("Automation", cols, filter);

I could go on forever around WSProxy, but we need to move on to the functions that are more designed to utilize the REST API. The first one up is HTTP.Get.

HTTP.Get

GET calls are usually made to retrieve or gather information from an outside source. Essentially meaning the script is dependent on the information gathered from an action. The Core version of a GET call is very simple and has very little available as options. It only has 3 properties to it:

  • URL
  • Header Names
  • Header Values

Outside of those, there is no other customization you can do to the call. This means that if the call returns anything other than a 200 OK status, that it will toss an error and blow up your entire script (unless you use Try/Catch of course) which can be infuriating. So yes, although it is simple and easy to use, it does come with some considerations and caveats when considering using it. For this consideration, I am including it in comparison to the two other GET focused functions (Platform.Function.HTTPGet and Script.Util.HttpRequest). They each have their own pros and cons.

The pros for this version is:

  • Simple and easy to use
  • No muss no fuss
  • Usually more performant and quicker than Platform version

The cons are:

  • Requires the Core library loaded
  • No customization for any added needs
  • No error handling or debugging outside Try/Catch
  • No caching capabilities for content syndication

Example:

var myGet = HTTP.Get('http://www.gortonington.com');

I will say that many people will use this call for a lot of their GET needs and it has shown measured success for them – I personally am not a huge fan. Next we move on to the POST version of this call – HTTP.Post.

HTTP.Post

Although the purposes are vastly different, the HTTP.Get and HTTP.Post functions are very similar. POST is usually used to create or add something – so usually this is directed to an action and is dependent on information provided in the script – quite the opposite of GET.

The Core version of a POST call is fairly simple as well.

It only has 5 simple properties to it:

  • URL
  • Content-Type header
  • Payload Content
  • Array of header names
  • Array of header values

As you may note, I say 5, but the official docs only show 4. Yes, this is an error in documentation as the 5th property is shown in the example, but was accidently removed from the table. All things said and done around this call, this call is much more flexible than the GET as it is the action, so you can control more with the addition of a payload.

This function, very similar to the GET version has pros and cons. Rather than list them out again, as they are pretty much identical, I will just say to go up and reference the GET pro/con list.

Example:

var url = 'http://gortonington.com';
var contentType = 'application/json';
var payload = '{"dog":"German Shepard"}';
var names = ["Header1", "Header2"];
var values = ["Value1", "Value2"];
var res = HTTP.Post(url, contentType, payload, names, values);

I know, I barely wrote anything here for this function, but honestly, its a very simple, utilitarian function – so it is what it is and does what it does. Therefore there is not much to really write on it.

Now that we have the Core versions done, let’s move on to the Platform GET and POST calls – starting with the Platform HTTPGet call.

Platform.Function.HTTPGet

To be fair, this call is pretty much just a wrapper for the AMPscript HTTPGet call. It has many of the same properties, aspects, considerations and performance issues. It is a non-Core call so there is no need to call the Core library in to use it, which in a way improves overall performance but honestly, that is not a huge gain here.

The really good news is that with this including the AMPscript properties, it goes from 3 properties in the Core function up to 5 propertires for the Platform version.

They are:

  • URL
  • Continue on Error
  • Empty Content Handler
  • Array of Header Names
  • Array of Header Values

There is also an unlisted 6th propert that can be used, which is basically a variable you place to house the results/status of the call. It will have no affect on the call itself, but it will give a return status that can be used in handling and debugging.

So as far as pros and cons – this has some advantages to the Core version:

Pros:

  • Built in error handling
  • Built in empty content handling
  • No Core library needed

Cons:

  • Still terrible error responses
  • More properties can make it harder to use and increase risk of human error
  • Low performance output in comparison to other options
  • No Caching capabilities

Here is an example of Platform GET:

var ret = Platform.Function.HTTPGet('https://www.gortonington.com',true,0,['Authentication'],['myToken'])

Next up is the Platform HTTPPost function, which is not hugely different from HTTP.Post and carries many of the same pros and cons as this function.

Platform.Function.HTTPPost

This call, similar to HTTPGet, is a wrapper for the AMPScript HTTPPost call. Not the HTTPPost2, but the regular HTTPPost. It is also not a Core library call, so there is no need to load the Core library in to use it.

As far as properties, it is the same as the Core HTTP.Post call, but this one listed the property of status in it.

  • URL
  • Content-Type
  • Payload content
  • Array of Header Names
  • Array of Header Values
  • Status Code returned

The syntax and structure of the call is near identical with the HTTP.Post Core function, and it has many of the same cons. Including no exception or error handling built in and little to no customization on the call. The major benefit here is that it does not require the Core library, so it gains performance that way. That being said though, as it is a wrapper of AMPscript, it also has its own performance issues.

Example:

var url = 'http://example.com/forms/myForm.html';
var contentType = 'application/json';
var payload = '{"name","value"}';
var names = ["header1", "header2"];
var values = ["value1", "value2"];
var result = Platform.Function.HTTPPost(url, contentType, payload, names, values);

Now we begin into the function I believe is the best function for using REST API inside of SFMC – Script.Util.HttpRequest.

Script.Util.HttpRequest

For a more in-depth dive into this function, please check my previous article REST API Methods in SSJS.

This function opens up many avenues of customization in making API calls that just are not available in the other functions. This includes utilizing methods other than just POST or GET. This function is very similar in many ways to the javascript function XMLHttpRequest(), but it is not a 1 to 1 match. There are many things that the JS version can do, as it interacts at the client level, that HttpRequest cannot as it is on the server level.

You can utilize the following methods in HttpRequest:

  • GET
  • DELETE
  • HEAD
  • OPTIONS
  • PATCH
  • POST
  • PUT

As to different properties that HttpRequest has, here is a list of a few of them:

url: This is the complete URL of the target of your API call.

emptyContentHandling – True/False on if it throws an error if content is empty

retries – number of retries it attempts before throwing a final exception

continueOnError – true/false for if it will continue the script/function if the result is an error

setHeader – will set a name/value pair for a header on the API call

method – sets the method used for the API call

postData – this is the ‘payload’ or data that is transferred to be digested by the receiving server

send() – this initiates the sending of the API call

There are some caveats that come with this though that you need to consider when deciding if this is the right function for your need. For instance, the results, Script.Util.Response, are in a CLR format – which is something that is not natively accepted via SSJS or AMPscript. So there will be some necessary hoops to jump through to get the data out. (See the article mentioned above for details) and not only that, but the function can be a bit more complex and involve more lines of code than other simpler HTTP.POST or HTTP.GET type functions. I personally have not seen any major differences in performance or speed, but it is also another consideration you need to have – I would recommend testing extensively to find what works best for you.

Example:

  var req = new Script.Util.HttpRequest(url);
  req.emptyContentHandling = 0;
  req.retries = 2;
  req.continueOnError = true;
  req.contentType = "application/json"
  req.setHeader("Authorization", auth);
  req.method = "PUT"; /*** You can change the method here ***/
  req.postData = payload;

  var resp = req.send();

Next, we will go to one of the best GET method functions out there when you need content syndication from an outside source in an email.

Script.Util.HttpGet

Why do I say this is the best GET method function for content syndication in email? Well, because this one caches content for use in mail sends, which can GREATLY increase your send time performance if it is not dynamic or customized content you are returning each time. I have seen sends drop sendtime dramatically when using this function instead of the default HTTP GET options.

HttpGet is structured and set up very similar to HttpRequest, so it might need more technical knowledge, but it is also well worth the extra time. This means it also includes a couple custom options similar to HttpRequest, like the ability to set, remove or clear headers from the call as well as retries, continue on error and more.

Although it may seem complex, it is a really simple function and one I highly recommend in any sending context that you need caching.

Example:

var req = new Script.Util.HttpGet(url);
var resp = req.send();

Well that is all the functions! I hope this is helpful to some when trying to make a choice on what to use for making API calls, as I know it is not always easy to find solid information on these. Let me know any I missed or any other information I should add or what I got wrong!

Tags: , , , , , , , , , , , , , , , , , ,
Subscribe
Notify of
guest
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tim Cerato
Tim Cerato
2 years ago

Such an underrated capability! While I wish SFMC had better support for webhooks in journeys, these capabilities add a ton of value. Great writeup!

Stephen Roper
Stephen Roper
2 years ago

This is a great breakdown of the various API call functions available within SSJS. Thanks for writing this up – super helpful!

Krish
Krish
1 year ago

Does the API call from SSJS consume any super message costs? Also could you please share if it is possible to use SSJS inside journey builder (other than in Email)?