The Workflow REST API allows you to perform any workflow action on a content object, things like saving, updating, translating, archiving and deleting. The workflow API allows you to specify what workflow action you would like to perform when saving/updating or deleting your content.
Available Methods
The fire
endpoint executes a Workflow Action. The fire
endpoint may be called using either the Workflow Action identifier or the Workflow Action name, or you call call fire ans specify a default action, e.g. EDIT or PUBLISH
Endpoint | Method | Usage | Description |
---|---|---|---|
/actions/fire | PUT | Executes the Workflow Action specified in the request body. | |
/actions/{actionId}/fire | PUT | Executes the specified Workflow Action. | |
/actions/default/fire/{defaultAction} | PUT | Executes the specified Default Workflow Action for the content (as specified in the Content Type of the content). For more information on Default Workflow Actions, please see the documentation on Default Workflow Actions. |
Contents of the Request
The fire
endpoint expects data in the body of the request with the JSON name "contentlet"
, which includes a list of the fields of the content and a “name” field which specifies the name of the application accessing the endpoint (for logging purposes).
If you wish to specify the Workflow Action via the action name, you must include an actionname
field as well. This field is not required when specifying the Workflow Action identifier in the URL.
/actions/fire
This method allows you to post content and specify a workflow action that you want to fire it through.
Saving new Content
PUT /api/v1/workflow/actions/fire
{
"actionName": "save", // workflow action name or action id
"comments": "saving content",
"contentlet": {
"contentType":"myBlog",
"title":"Amazing Content",
"urlTitle": "amazing-content",
"siteOrFolder":"demo.dotcms.com",
"publishDate":"2019-12-18 10:00:00",
"tags": "tag one, tag two",
"body": "<h1>This content is amazing</h1><div>but not this</div>",
"languageId": "1"
}
}
Updating Existing Content By Identifier
PUT /api/v1/workflow/actions/fire
{
"actionName": "save", // workflow action name or action id
"comments": "saving content", // include a workflow comment
"contentlet": {
"identifier":"fec7b960-a8bf-4f14-a22b-0d94caf217f0" // the identifier of the content you are updating
"title":"Amazing Content Again",
"urlTitle": "my-second-url-title",
"siteOrFolder":"demo.dotcms.com",
"publishDate":"2019-12-18 11:00:00",
"tags": "tag one, tag two",
"body": "<h1>This is an EDITED content<h2><div>but not this</div>",
"languageId": "1"
}
}
Executing a workflow action on a piece of content
PUT /api/v1/workflow/actions/fire?identifier=fec7b960-a8bf-4f14-a22b-0d94caf217f0
{
"actionName": "Publish",
"comments": "publishing content"
}
/actions/{actionId}/fire
Updating Existing Content By Identifier
PUT /api/v1/workflow/actions/a22b0d94caf217f0/fire // workflow action id
{
"comments": "saving content", // include a workflow comment
"contentlet": {
"identifier":"fec7b960-a8bf-4f14-a22b-0d94caf217f0" // the identifier of the content you are updating
"title":"Amazing Content Again",
"urlTitle": "my-second-url-title",
"siteOrFolder":"demo.dotcms.com",
"publishDate":"2019-12-18 11:00:00",
"tags": "tag one, tag two",
"body": "<h1>This is an EDITED content<h2><div>but not this</div>",
"languageId": "1"
}
}
/actions/default/fire/{defaultAction}
The default fire endpoint gives developers consistent endpoints that can optionally be mapped to perform a additional workflow actions, without having to know an actionId beforehand. dotCMS allows administrators to set “Default Actions” that execute when a content object PUT against these endpoints. These “Default” actions map an internal dotCMS content lifecycle action to specific workflow action which are executed for the content when these endpoints are called. If there is no default workflow action specified for content type or the content types workflow, the content will perform the lifecycle event - SAVE/PUBLISH/UNPUBLISH/DELETE and return normally
All the default actions, save the NEW and EDIT, optionally take a {contentlet:xxxx}
body that will be persisted when the endpoint is called.
Available default actions
Operation | Use when |
---|---|
/actions/default/fire/NEW | Creating new content |
/actions/default/fire/EDIT | Editing content, saving as draft |
/actions/default/fire/PUBLISH | To publish the content |
/actions/default/fire/UNPUBLISH | To the unpublish content |
/actions/default/fire/ARCHIVE | To archive the content |
/actions/default/fire/UNARCHIVE | To unarchive the content |
/actions/default/fire/DELETE | To delete all versions of a content in a single language |
/actions/default/fire/DESTROY | To delete all versions of a content in a ALL languages |
Saving New Content
PUT /actions/default/fire/NEW
{
"contentlet": {
"contentType":"webPageContent",
"title":"Amazing Content",
"siteOrFolder":"demo.dotcms.com",
"body": "<h1>This content is amazing</h1><div>but not this</div>",
"languageId": "1"
}
}
Saving Multiple Pieces of New Content
POST /actions/default/fire/NEW
{
"contentlets":[
{
"contentType":"Test1",
"title":"Content1",
"languageId": "1",
"body":"Body Content1"
},
{
"contentType":"Test1",
"title":"Content2",
"languageId": "1",
"body":"Body Content2"
},
{
"contentType":"Test1",
"title":"Content3",
"languageId": "1",
"body":"Body Content3"
}
]
}
Publishing Content
PUT /actions/default/fire/PUBLISH
{
"contentlet": {
"contentType":"webPageContent",
"title":"Published Content",
"siteOrFolder":"demo.dotcms.com",
"body": "<h1>This content is amazing</h1><div>but not this</div>",
"languageId": "1"
}
}
Publishing Multiple Pieces of Content
POST /actions/default/fire/PUBLISH
{
"contentlets":[
{
"contentType":"webPageContent",
"title":"Content1",
"contentHost":"default",
"body":"Body Content1"
},
{
"contentType":"webPageContent",
"title":"Content2",
"contentHost":"default",
"body":"Body Content2"
},
{
"contentType":"webPageContent",
"title":"Content3",
"contentHost":"default",
"body":"Body Content3"
}
]
}
Unpubishing Content
PUT /actions/default/fire/UNPUBLISH?identifier=e5b3e417-b0c9-450c-87ba-dda0e2782cb3
Archiving Content
PUT /api/v1/workflow/actions/default/fire/ARCHIVE
{
"contentlet": {
"identifier":"e5b3e417-b0c9-450c-87ba-dda0e2782cb3",
"contentType":"webPageContent",
"title":"ARCHIVED Content",
"contentHost":"default",
"body": "I'M ARCHIVED!",
"languageId": "1"
}
}
Files / Multipart Form Data
Sending multipart/form-data is supported, and is required in order to send file content for Binary fields.
Content Type Header
The format of the content should be specified in the Content-Type
header. Supported Content-Types include:
- application/json
- application/x-www-form-urlencoded
For more information on submitting content using these content types, please see Data Formats, below.
Authentication
This API supports the same REST authentication methods as other REST APIs in dotCMS. Please read the REST API Authentication documentation for details on the different methods and how to use them when saving content using the REST API.
Anonymous Access
Note, by default dotCMS respects the permissions set on the content type that is being persisted. This means that all users, anonymous or otherwise, may save content via the REST API if they have permissions on the content type and or site they are saving content to.
Anonymous access can be limited by changing the dotmarketing-config.properties file:
CONTENT_APIS_ALLOW_ANONYMOUS=WRITE=write
Possible values are NONE
| READ
| WRITE
The CONTENT_APIS_ALLOW_ANONYMOUS
controls what level of access to grant ANONYMOUS (not logged in) visitors to dotCMS Content apis. This property is only respected by the APIs that have to do with mananging content in the dotCMS content store. For anonymous content submittal to work (form builder, contentAPI) CONTENT_APIS_ALLOW_ANONYMOUS
needs to be set to WRITE, otherwise users will need to authenticate before subitting content
- Set permissions to allow the CMS Anonymous user to save content of the appropriate Content Types.
- Grant Add to permissions to the CMS Anonymous role on the Site where the content will be saved using the REST API.
- Grant Edit permissions to the CMS Anonymous role on each Content Type which will be added or updated via the REST API.
For more configuration on how access to the REST API can be controlled via configuration, please see the REST API Authentication documentation.
Data Formats
You may submit data via the Content REST API using either JSON or FORM. The following examples demonstrate ways to submit content via the REST API using JSON, and Form UrlEncoded formats, both to create new content and to update existing content.
Field Types
The following examples demonstrate how to send content for several additional types of Content Type fields.
Field Value Formats
All field values are passed in the json object as strings. Below is a list of field types in dotCMS and the supported formats for each type:
Field Type | Supported Formats |
---|---|
Binary | Please see Binary Fields, below. |
Category | A string containing a comma separated list of Category ids, Category keys, or Category variable names. (e.g. "investing,research,wealthManagement" ).Please see Categories, below. |
Checkbox, Multi-Select | A string containing a comma separated list of selected values (the strings to the right of the pipe (\ |
Constant Field, Hidden Field | Should not be submitted with the content item. (These are filled in automatically by dotCMS). |
Custom Field | A string containing the field value (as formatted by your Custom Field code). |
Date, Time, Date and Time | yyyy-MM-dd HH:mm:ss , yyyy-MM-dd HH:mm , d-MMM-yy , MMM-yy , MMMM-yy , d-MMM , dd-MMM-yyyy , MM/dd/yyyy hh:mm:ss aa , MM/dd/yyyy hh:mm aa , MM/dd/yy HH:mm:ss , MM/dd/yy HH:mm:ss , MM/dd/yy HH:mm , MM/dd/yy hh:mm:ss aa , MM/dd/yy hh:mm:ss , MM/dd/yyyy HH:mm:ss , MM/dd/yyyy HH:mm , MMMM dd, yyyy , M/d/y , M/d , EEEE, MMMM dd, yyyy , MM/dd/yyyy , hh:mm:ss aa , hh:mm aa , HH:mm:ss , HH:mm , yyyy-MM-dd .Note: You may use formats that only include the date or time for Date and Time fields, but you may not use a format which includes both the date and time for Date fields or Time fields. |
File, Image | The path to the related file, starting with the hostname (e.g. "//demo.dotcms.com/images/photos/The-Gherkin-London-England.jpg" ). |
Key/Value | Please see Key/Value Pair Fields, below. |
Radio, Select | A string containing the selected value for the field (the string to the right of the pipe (\ |
Relationship | Please see Relationships, below. |
Site or Folder | A string representing the host (e.g. "demo.dotcms.com" ), a folder (for the host the user is on) (e.g. "/images/photos" ), or a combination of host and folder (e.g. "demo.dotcms.com:/images/photos/" . |
Tag | A comma separated list of tag values (e.g. "investment,banking,europe" ). |
Text | A string containing the field value. |
Textarea | A string containing the field value. Non-printing characters should be escaped using HTML escape codes (e.g. %0D%0A for carriage-return line-feed). |
WYSIWYG | A string containing the field value, containing HTML formatting. Non-printing characters should be escaped using HTML escape codes (e.g. %0D%0A for carriage-return line-feed). |
Categories
Categories can be specified using a comma separated list. Each item in the list will be checked first to see if it matches a Category inode, then to see if it matches a Category key, and finally to see if it matches a Category variable name. If any of these are matched, the appropriate Category will be set for the content item.
The following example adds a News content item on the dotCMS demo site (uploading categories variable names):
PUT /api/v1/workflow/actions/default/fire/PUBLISH
{
"contentlet": {
contentType:"webPageContent",
languageId:1,
urlTitle:"a-new-news-item",
hostfolder:"demo.dotcms.com",
title:"A new news item",
byline: "this is a new story",
sysPublishDate: "2013-07-01 00:00:00",
story: "this is a new story uploaded from cURL",
topic: "investing,banking,research"
}
}
Binary Fields
Files can be uploaded into Binary fields using multipart/form-data.
- Portions of the API call using JSON, XML or Form UrlEncoded data are interpreted as normal field values.
- Portions of the API call using a
Content-Disposition
header are added as Binary field values.
Single or multiple binary files can be uploaded as part of a piece of content. Regardless of which method is used, all required binary fields on the Content Type must be submitted.
Uploading a Single Binary File
The following curl command submits a single binary image to a File Asset type of content using the REST API. Note the JSON portion of the API call to set the regular field values, and the file included using @
(which will submit the specified file to the first Binary field in the Content Type).
curl --location --request PUT 'http://localhost:8082/api/v1/workflow/actions/default/fire/NEW?language=1589383514071' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic XXXXXXXXXXXXXXXXX==' \
--form 'file=@testpdf.pdf' \
--form 'json={
"contentlet": {
"contentType":"PDFDotAsset",
"title":"Test1",
"contentHost":"demo.dotcms.com"
}
}
'
Uploading Multiple Binary Fields
The following curl command submits a File Asset using the REST API with two binary fields. The names of the two fields are fileAsset
and image2
. Note the JSON portion of the API call to set the regular field values, and the file included using @
(which will submit the specified file to the Binary fields in the order expressed using in the binaryFields
parameter that has been added to the curl command).
Important Note: Notice that the binaryFields
parameter is ordering the submit of the files to the fields in the content. When using the binaryFields
parameter:
- The order of the fields submitted to the parameter determines which fields the binary files will be uploaded.
- Non-required binary fields may be omitted — e.g., if the Content Type has 4 non-required binary fields, supplying the names of only the 2nd and 3rd fields to the
binaryFields
parameter will upload only two binary files to those specified fields and leave the other two Binary fields empty. - The number of fields supplied to the
binaryFields
parameter must match the number of files that are appended at the end of the REST API submit. - The names of each binary field will match the file name specified in the REST API submit. More flexibility on multiple binary field naming will added in a future dotCMS version.
The curl command below uses the binaryFields
parameter two upload two files to a new contentlet of the File Asset type. The order of the fields supplied to the parameter, in the example provided below, determines which fields the appended files will be uploaded to respectively i.e., test1.png
will be uploaded to the fileAsset
field, and test2.png
will be uploaded to the image2
field.
curl --location --request PUT 'https://demo.dotcms.com/api/v1/workflow/actions/default/fire/PUBLISH' \
--header 'Authorization: Basic XXXXXXXXXXXXXX==' \
--header 'Cookie: JSESSIONID=XXXXXXXX; access_token=XXXXXXXXX' \
--form 'json="{
\"contentlet\": {
\"stInode\": \"49f7f5904c2c10d3a4ada6b2e9cc2fc1\",
\"title\":\"Test\",
\"hostFolder\":\"demo.dotcms.com\"
},
\"binaryFields\": [
\"fileAsset\",\"image2\"
]
}"' \
--form 'file=@"/Users/erickg/Pictures/test1.png"' \
--form 'file=@"/Users/erickg/Pictures/test2.png"'
Key/Value Pair Fields
In the following example, a Key/Value pair field on a Content Type called “Television” has the Velocity variable name of “productSpecifications”. As shown in the example below, keys and values can be sent via REST API using the following form: fieldVelocityVariableName:{"mykey1:"myValue1","mykey2:"myValue2",... etc.}
. Note the handling of the “productSpecifications” key/value pair field.
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/NEW -H "Content-Type:application/json" -d '{
"contentlet":
{
contentType:"Television",
languageId:1,
contentHost:"demo.dotcms.com",
brandAndModel:"Samsung UN65JS9500",
resolution:"Ultra HD",
screenSizeinches:"65",
productSpecifications:{"Refresh Rate":"240 CMR (Effective)","Backlight":"LED","Smart Functionality":"Yes - Built in Wifi","Inputs":"2 HDMI, 2 USB"}
}
}'
Relationships
Beginning with the dotCMS 5.1.x dotCMS series, one sided relationships were introduced to make individual relationships fields viewable/editable/searchable individually on either side of the content relationship. To learn more about these changes, please see the Relating Content on Content Types and Relating Content documentation. If you are upgrading from a pre-5.1 dotCMS version, please see the Migrating Legacy Relationships documentation.
The examples below show how to submit related content via REST API using one-sided relationship fields. This methodology works for One-to-One, One-to-Many, or Many-to-Many relationships.
Submiting Related Content with Relationship Fields
To relate content, you must specify the variable name of the Relationship field, and set the value to a string with one or more lucene queries and/or content identifiers, separated by commas. For content that already has existing relationships, you may delete, replace, or preserve the existing relationships by passing the appropriate value to the Relationship field, as follows:
Information Passed to the Relationship Field | Results |
---|---|
Empty String (e.g. "" ) | Remove all existing relationships (if any). |
String of queries/ids (separated by commas) | Replace existing relationships (if any) with the specified relationships. |
No relationship field passed | Preserve (make no changes to) existing relationships (if any). |
When submiting related content via the REST API, use the following format:
Relate a single piece of content by identifier
{relationship field velocity variable name}:"{identifier}"
Relate a multiple pieces of content by identifier
{relationship field velocity variable name}:"{identifier,identifier,...}"
Relate one or more pieces of content using a lucene query
{relationship field velocity variable name}:"{lucene query}"
Relate one or more pieces of content using a comma separated list of lucene queries and identifiers
{relationship field velocity variable name}:"{lucene query},{identifier},{lucene query},{identifier}"
Examples of Curl commands submitting related content using either identifier or lucene query
Create New Employee with Query for Location Identifier
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/NEW \
-H "Content-Type:application/json" -d '{
"contentlet": {
contentType:"Employee",
languageId:1,
firstName:"Dean",
lastName:"Gonzalez",
gender:"male",
jobTitle:"General Manager",
email:"dean@dotcms.com",
location:"+identifier:0c69da5c-2a05-452f-9305-3be6926d5079"
}
}'
Create New Employee with Lucene Query for “South America” as Location Office Name
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/NEW \
-H "Content-Type:application/json" -d '{
"contentlet": {
contentType:"Employee",
languageId:1,
firstName:"New",
lastName:"Person",
gender:"male",
jobTitle:"General Manager",
email:"person@dotcms.com",
location:"+contentType:Location +Location.title:\"South America\""
}
}'
Submit new Location and Relate to Many Employees with Job Title of President
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/NEW \
-H "Content-Type:application/json" -d '{
"contentlet": {
contentType:"Location",
host1:"48190c8c-42c4-46af-8d1a-0cd5db894797",
languageId:1,
title:"Melbourne Office",
country:"Australia",
address1:"1122 Aussie Avenue",
city:"Melbourne",
segment:"banking,investing",
description:"Melbourne Australia Office",
employees:"+contentType:Employee +Employee.jobTitle:President*"
}
}'
Submit new Location and Relate to Many Employees with Job Title of President and an Employee Identifier
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/PUBLISH \
-H "Content-Type:application/json" -d '{
"contentlet": {
contentType:"Location",
host1:"48190c8c-42c4-46af-8d1a-0cd5db894797",
languageId:1,
title:"Melbourne Office",
country:"Australia",
address1:"1122 Aussie Avenue",
city:"Melbourne",
segment:"banking,investing",
description:"Melbourne Australia Office",
employees:"+contentType:Employee +Employee.jobTitle:President*,37f93fcb-6124-46af-83b4-9ece6c1c5380"
}
}'
Update an Employees Passing Employee Identifier and Identifier of Office Location to the Location Field
Please note that the employee's relationship to ANY current office location would be replaced by the new office location being passed to the relationship field
curl -v -u admin@dotcms.com:admin -XPUT http://localhost:8082/api/v1/workflow/actions/default/fire/PUBLISH \
-H "Content-Type:application/json" -d '{
"contentlet": {
contentType:"Employee",
identifier:"74ebbf55-2821-4b51-8e66-78d54c839991",
location:"6f19f0a0-f407-4f4c-8c01-58daf6659321"
}
}'