One of the many hiccups people face when trying to interact with SFMC via API is that some parts just cannot be touched, even in SOAP. Script Activities, Cloud pages, and Microsites to name a few. Luckily for us, there is a way to actually interact with Script Activites via API, it is just undocumented.

Even better, it is all via REST API, not SOAP. Ok, now that you have calmed down and resumed reading, below is the quick documentation I created around these endpoints.

Please note that as they are not officially documented, they likely are not officially supported. Which of course means that there are possible bugs and no where to find support for any issues you have.

Create New Script

POST /automation/v1/scripts
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

{
   "name": "RestAPIScript",
   "key": "RestAPIScript",
   "description": "",
   "script": "<script runat=\"server\">\n   Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
   "categoryId": 12345
}

This will create a new Script Activity named ‘RestAPIScript’ inside the folder with an id of 12345 (categoryId).

Example Response:

{
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript",
    "key": "RestAPIScript",
    "description": "",
    "script": "<script runat=\"server\">\n   Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX,
    "folderLocationText": "Scripts",
    "parentCategoryId": []
}

Update Existing Script

PATCH /automation/v1/scripts/{{scriptObjectId}}
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

{
    "ssjsActivityId": "{{scriptObjectId}}",
    "description": "",
    "script": "<script runat=\"server\">\n   Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345
}

This will update an existing Script Activity. Please note that it has the scriptObjectId twice. Once in the URL (at the end) and once in the payload (“ssjsActivityId”). This is necessary (for the time being anyway) otherwise it will not work.

Example Response:

{
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript",
    "key": "RestAPIScript",
    "description": "",
    "script": "<script runat=\"server\">\n   Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
}

Get Existing Script

GET /automation/v1/scripts/{{scriptObjectId}}
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

This will get you the information about an existing script (based on scriptObjectId) including the script itself.

Example Response:

{
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript",
    "key": "RestAPIScript",
    "script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
}

Get All Existing Scripts:

GET /automation/v1/scripts/
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

This will return an array of all existing scripts in the account. Utilizing the ContentBuilder documented $filter capabilities work on this endpoint. For instance, you can do ?$filter=name%20like%20'_' to get all your script activities that contain an underscore.

Example Response:

{
    "count": 2,
    "page": 1,
    "pageSize": 25,
    "items": [
        {
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript",
    "key": "RestAPIScript",
    "script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
        },
        {
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript2",
    "key": "RestAPIScript2",
    "script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
      }
    ]
}

Get All Scripts Inside of a Folder:

GET /automation/v1/scripts/category/{{categoryId}}
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

This will return an array of all the scripts inside of a specific folder (based on categoryId).

Example Response:

{
    "count": 2,
    "page": 1,
    "pageSize": 25,
    "items": [
        {
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript",
    "key": "RestAPIScript",
    "script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
        },
        {
    "ssjsActivityId": "{{scriptObjectId}}",
    "name": "RestAPIScript2",
    "key": "RestAPIScript2",
    "script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>",
    "categoryId": 12345,
    "statusId": 1,
    "status": "Active",
    "createdDate": "0001-01-01T00:00:00",
    "modifiedDate": "0001-01-01T00:00:00",
    "createdBy": XXXXXX,
    "modifiedBy": XXXXXX
      }
    ]
}

Validate a Script:

POST /automation/v1/scripts/validate/
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

{
	"script": "<script runat=\"server\">\n    Platform.Load(\"Core\",\"1.1.1\");\n    var stream = ContentAreaByName(\"some-content-area-name\");\n    Write(TreatAsContent(stream));\n</script>"
}

This will let you validate your SSJS prior to creation or update inside the system. The return is a boolean value, essentially pass/fail. Please note this is just for validation of the code, it does not verify the dependents (content areas, DEs, etc.) so it does not guarantee there will be no errors when run.

Example Response:

{
    "scriptValid": true
}

Start A Script Activity:

POST /automation/v1/scripts/{{scriptObjectId}}/start 
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

This will run the script activity based on the scriptObjectId provided. Returns “OK” when successful.

Delete a Script Activity:

DELETE /automation/v1/scripts/{{scriptObjectId}}
Host: {{yourendpoint}}.rest.marketingcloudapis.com
Authorization: Bearer {{authToken}}
Content-Type: application/json

This will delete a script activity based on the scriptObjectId provided. Returns “OK” when successful.

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback
How to interact with Query Activities via REST API | Gortonington
3 years ago

[…] As many of you may know, I am a big fan of the undocumented REST API endpoints. I do have my first dive into them in my previous post Access Script Activities via API. […]