Please rate how useful you found this document: 
No votes yet

Advanced Developer


Read and consult the ProcessMaker wiki when working with the REST API of ProcessMaker:

Additional resources:

Remember that REST is not a real-time communication interface.

OAuth 2.0

  • Every ProcessMaker user who logs in using the REST API will need to register from a separate application because the Client ID and Client Secret codes only work for a single user (read more here).
  • Google Chrome doesn't allow cookies for localhost or numbered IP addresses, such as See this workaround (read more here).
  • It generally takes a few microseconds for a cookie to be saved, so a new cookie will not be immediately available after it is set with the setcookie() function.To use the new access token immediately after calling the pmRestLogin() function, it is recommended to get the access token from the return value of the function rather than using $_COOKIE['access_token']. For this reason, $oToken->access_token is passed as a parameter to pmRestRequest() in the above example (read more here).
  • The scope can have multiples values separated by a single space or its URL encode equivalent, %20. Set the scope to * to include all available scopes (read more here).
  • The client_id and client_secret can be omitted from the POST parameters if they are set as the username and password in the HTTP header (read more here).

Calling REST Endpoints

The best way to call a REST endpoints are the following:

Before Using Endpoints

  • Work with tools such as POSTMAN to verify and learn about the functionality of the endpoints.
  • Before working with an endpoint, make sure to know its required parameters. To find out which parameters are required by each endpoint, read the information about each in the ProcessMaker wiki.
  • When working in the application, take into account that all endpoints return a success or error message after making a request.



  • When getting the information about a user through the GET /users list, the "usr_city" attribute is named incorrectly. See the wf_<workspace>.ISO_SUBDIVISION table in the database (read more here).
  • If using PHP, make sure to place @ in front of the path to suppress error messages. Otherwise, the POST /user/{usr_uid}/image-upload endpoint will not work.
  • The DELETE user endpoint sets the wf_<workspace>.USERS.USR_USERNAME field to "" (empty string) in the database to disable the user, but it does NOT delete the user's record from the database (read more here).
  • Note that it is possible to add a user with "INACTIVE" or "VACATION" status to a group, but that user will not be assigned to any cases until his/her status changes to "ACTIVE" using the PMFAssignUserToGroup() ProcessMaker function: POST /group/{grp_uid}/user.


  • Note that the department's title must be unique, so an error will occur if trying to create a department title that already exists (read more here).
  • The dep_last element in the returned object is always set to 0 and is not correct. To check whether the new department is the last department at the current level, call the GET /departments or GET /department/{dep_uid} endpoint and check the value of the dep_last element (read more here).
  • Note that it is not possible to delete a department while it has assigned users, so all the users must be unassigned from the department before deleting it (read more here).


  • Note that it is not possible to delete a role that still has assigned users, so all users must be assigned to different roles before deleting the role (read more here).
  • The admin user may be returned by the GET /role/{rol_uid}/available-users endpoint, but cannot be reassigned to another role.
  • Note that the admin user may not be reassigned to a different role, and if attempted will generate the following error message:
        "error": {
            "code":    400,
            "message": "Bad Request: The role of the administrator can not be changed!"
    (read more here).


  • Note that the DELETE /group/{grp_uid} endpoint deletes the group's record from the GROUPWF table and its title from the CONTENT table in the database, but it doesn't delete the group's membership list from the GROUP_USER table.

PM Tables

  • The field names are automatically converted to lowercase (read more here).
  • Integers, floating-point numbers (real numbers) and boolean values are converted to strings. In the example above, the ID is an integer and has_contract is a boolean in MySQL. Also, __index__ field is automatically created by MySQL to index the PM table (read more here).
  • If using PHP, the POST variables will need to be passed through the http_build_query() method, which will cause problems with fields that include fld_size. The ProcessMaker source code needs to be changed to avoid an error (read more here).
  • Remember that ProcessMaker's MySQL database stores character data using the UTF-8 character set, so strings should be converted to UTF-8 if they are in another character set, using a function like iconv() in PHP (read more here).

Report Tables

  • To export and import report tables correctly, remember that the APP_NUMBER can NOT be removed from the report table.

Case Tracker

  • When working with the Case Tracker endpoints, take into account that cto_type_obj and cto_uid_obj are dependent variables, thus if one of them is sent, the other must be sent (read more here).



  • To claim a case using the GET /api/1.0/{workspace}/cases/unassigned endpoint, the logged-in user must either be assigned as a user or an ad hoc user to the case's current task.
  • The GET /api/1.0/{workspace}/cases/{app_uid}/tasks endpoint does not indicate whether a case has been canceled, paused or completed. The task The task status property it returns can be deceptive, since it returns "TASK_COMPLETED" when all the steps are completed but before routing to the next task. To find the overall status of a case, or to confirm which task is the current task, it is recommended to call another endpoint, such as GET api/1.0/{workspace}/cases/{app_uid}, to check its app_status and current_task (read more here).
  • When using the PUT /api/1.0/{workspace}/cases/{app_uid}/reassign-case endpoint to reassign a case, note that the logged-in user needs to have the PM_REASSIGNCASE permission assigned to his/her role to be able to reassign the case.
  • If using the PUT /api/1.0/{workspace}/cases/{app_uid}/execute-trigger/{tri_uid} endpoint, note that the trigger can be executed, even if it is not assigned to fire in the case's process.
  • For GET /api/1.0/{workspace}/api/1.0/{workspace}/cases/{app_uid}/variables, note that this endpoint can return the variables from any case, regardless of its status, so it can get the variables for paused, completed or even canceled cases.
  • Dynaform fields that have integer or float variables have their values stored as strings, so it may be necessary to convert their values to numbers to do mathematical operations. Grids and the results of database queries are stored as an associative array of associative arrays in ProcessMaker, but they are converted into an object of objects, because JSON doesn't support associative arrays. When reading this object of objects in PHP, it is recommended to either use json_decode($json, true) to convert the return object into an associative array or get_object_vars() to convert the rows in a grid to an associative array. See the example below.

    PHP Example:
    The code below uses the case variables returned and converts the "reviewersList" grid from an object to an associative array and then loops through that array to print out the names of the reviewers and their decision to approve or reject a contract.

    $caseId = '78484118955bbd5fc39e5c5072875367';
    $url = "/api/1.0/workflow/cases/$caseId/variables";
    $method = "GET";
    $oRet = pmRestRequest($method, $url);
    if ($oRet->status == 200) {
       $oVars = $oRet->response;
       //convert grid from object to associative array:
       $oVars->reviewerList = get_object_vars($oVars->reviewerList);
       echo "Contractor: {$oVars->contractor}\nAmount: {$oVars->amount}\nReviewers:\n";

       for ($i = 1; $i <= count($oVars->reviewerList); $i++) {
          echo "$i. {$oVars->reviewerList[$i]->name}: {$oVars->reviewerList[$i]->approved_label}\n";
    (read more here)
  • It is not possible to remove an existing variable using the PUT /api/1.0/{workspace}/api/1.0/{workspace}/cases/{app_uid}/variable endpoint, so it is recommended to instead set the variable to "" (an empty string). The only way to completely remove a variable to execute a trigger that unsets the variable unset(@@my_var). Another way to unset the variable is to remove the variable from the serialized string of variables stored in the wf_<WORKSPACE>.APPLICATION.APP_DATA field in the database. The following PHP code unsets @@my_var outside a trigger:
    $caseId = "37213410154d375de3e3620044382558";
            //set to server address, mysql user and mysql password:
            $link = mysql_connect('localhost', 'root', 'p4sSw0rd') or die(mysql_error());
            //set to workspace database:
            mysql_select_db('wf_workflow', $link) or die(mysql_error());
            $result = mysql_query("select APP_DATA from APPLICATION where APP_UID = '$caseId'") or
            $row = mysql_fetch_array($result) or die("Unable to fetch data for case $caseId");
            $aVars = unserialize($row['APP_DATA']);
            $sVars = mysql_real_escape_string(serialize($aVars));
            $result = mysql_query("update APPLICATION set APP_DATA = '$sVars' where APP_UID = '$caseId'") or

Input Documents

  • When using the GET /api/1.0/{workspace}/cases/{app_uid}/input-documents endpoint, note that only input document files are returned when the user logged in has one of the following rights to view the files:
    • The input document is a step in the current task of the case and the logged-in user is currently assigned to work on the case.
    • The user logged in has process permissions to view the task where the input document is a step.
  • Note that it is possible to get the list of input documents in a case regardless of the case's status, so it is possible to get the input document files in cases that have been paused, canceled or completed if the user has the correct process permissions. (read more here)
  • The user logged-in may only see information about Input Document files if he/she is currently assigned to the case, or has the correction process permissions to see the Input Document to which the files were uploaded (read more here).
  • To upload an input document using the POST /api/1.0/{workspace}/cases/{app_uid}/input-document endpoint, note that the user logged in must either be currently assigned to work on the case, or be a Process Supervisor with permissions to access the input document; otherwise, this endpoint returns an HTTP status code of 302.
  • If using PHP to send POST fields to REST endpoints that contain objects or arrays, the POST fields have to be encoded with the http_build_query() function. However, passing the filename through the http_build_query() function mangles it, and the endpoint will return a status code of 400 with the message "Bad Request: This filename does not exist!". Either make a pmRestRequest() function that doesn't use the http_build_query() function, or use code like the example below to upload the file (read more here).
  • If the uploaded file is larger than the upload_max_filesize setting in the php.ini file on the ProcessMaker server, then the HTTP status code will be 413 with the error message "Request Entity Too Large: Uploaded file (filename) is too big.". If the uploaded file is larger than the post_max_size setting in the php.ini file on the ProcessMaker server, then the endpoint will return a status code and the message "Bad Request: `tas_uid` is required but missing" (read more here)
  • The DELETE /api/1.0/{workspace}/cases/{app_uid}/input-document/{app_doc_uid} endpoint does not delete the record of the Input Document file from the database, nor does it delete the file on the server's harddrive, stored at <install-directory>/shared/sites/<workspace>/files/XXX/XXX/XXX/XXXXXXXXXXXXXXXXXXXXXXX/<app_doc_uid>_<version>.<extension>, where XXX... is the app_uid <case ID>. All it does change the value of the wf_<workspace>.APP_DOCUMENT.APP_DOC_STATUS field in the database from "ACTIVE" to "DELETED" so the file will not appear in the ProcessMaker interface. Therefore, the deletion of the file can be undone by updating the database record to change the status back to "ACTIVE" (read more here).

Output Documents

  • Note that if the user logged-in doesn't have the proper permissions to view the generated output documents, or if there are no generated output documents in the case, then an empty array will be returned (read more here).
  • This endpoint does not delete the record of the generated output document located in the wf_<workspace>.APP_DOCUMENT table in the database, nor does it delete the physical file(s) from the file system, which are located at: <Install-Directory>/shared/sites/<workspace>/files/XXX/XXX/XXX/XXXXXXXXXXXXXXXX/outdocs/<app_doc_uid>, where XXX... is the app_uid. Instead, it simply changes the value of the wf_<workspace>.APP_DOCUMENT.APP_DOC_STATUS field in the database from "ACTIVE" to "DELETED" so that the files can not be seen in the ProcessMaker interface. Changing this value back to "ACTIVE" in the database will undelete the file (read more here).

Case Notes

  • Only users who have been assigned the process permissions for case notes may access them. Even the user who is currently assigned to work on the case may not see the case notes without the proper process permission for case notes. If the user logged-in doesn't have the proper permissions to access case notes, the following error object is returned:
        "error": {
            "code":    400,
            "message": "Bad Request: You do not have permission to access the cases notes"
    (read more here)