Save Content with Workflows documentation for the dotCMS Content Management System

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

EndpointMethodUsageDescription
/actions/firePUTExecutes the Workflow Action specified in the request body. 
/actions/{actionId}/firePUTExecutes the specified Workflow Action. 
/actions/default/fire/{defaultAction}PUTExecutes 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 is a 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 consistant 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

OperationUse when
/actions/default/fire/NEWCreating new content
/actions/default/fire/EDITEditing content, saving as draft
/actions/default/fire/PUBLISHTo publish the content
/actions/default/fire/UNPUBLISHTo the unpublish content
/actions/default/fire/ARCHIVETo archive the content
/actions/default/fire/UNARCHIVETo unarchive the content
/actions/default/fire/DELETETo delete all versions of a content in a single language
/actions/default/fire/DESTROYTo 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 is a content is amazing</h1><div>but not this</div>",
      "languageId": "1"
  }
}   
Publishing Content
PUT /actions/default/fire/PUBLISH
{
    "contentlet": {
      "contentType":"webPageContent",
      "title":"Published Content", 
      "siteOrFolder":"demo.dotcms.com",
      "body": "<h1>This is a content is amazing</h1><div>but not this</div>",
      "languageId": "1"
  }
}   
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

  1. 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 TypeSupported Formats
BinaryPlease see Binary Fields, below.
CategoryA 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 FieldA 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/ValuePlease 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 (\
RelationshipPlease see Relationships, below.
Site or FolderA 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/".
TagA comma separated list of tag values (e.g. "investment,banking,europe").
TextA string containing the field value.
TextareaA string containing the field value.
Non-printing characters should be escaped using HTML escape codes (e.g. %0D%0A for carriage-return line-feed).
WYSIWYGA 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:8080/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 “newBinary”. 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 binary_fields parameter that has been added to the curl command).

Important Note: Notice that the binary_fields parameter is ordering the submit of the files to the fields in the content. When using the binary_fields parameter:

1. The order of the fields submitted to the parameter determines which fields the binary files will be uploaded to
2. 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 binary_fields parameter will upload only two binary files to those specified fields and leave the other two binary fields empty.  
3. The number of fields supplied to the **binary_fields** parameter must match the number of files that are appended at the end of the REST API submit  
4. The names of each binary field will match the **fileName** 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 binary_fields parameter two upload two files to a new contentlet of type “File Asset”. 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., test9.jpg will be uploaded to the fileAsset field, and test10.jpg will be uploaded to the bin2 field.

curl --location --request PUT 'http://localhost:8080/api/v1/workflow/actions/default/fire/NEW?language=1589383514071' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic XXXXXXXXXXXXXXXXX==' \
--form 'file=@fileAsset.pdf' \
--form 'file=@newBinary.pdf' \
--form 'json={
     "contentlet": {
        "contentType":"PDFDotAsset",
        "title":"Test1",
        "contentHost":"demo.dotcms.com"
    }
}

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:8080/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 FieldResults
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 passedPreserve (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:8080/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:8080/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:8080/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:8080/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:8080/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"
   }
}'