Skip to main content
Known Participant
Oct 2, 2025 2:06 PM UTC

Power Automate Proof of Concept: Create a new Service Request

I didn't see many screenshots or detailed examples of Power Automate use for Cityworks API so here's my little offering:

 

I'm on 23.10. I'm an API and programming newby, so please offer any advice, tips, or tricks if you have them. I am lucky to be allowed the latitude to do a lot of testing and playing around since I happen to also be the Cityworks Administrator. Hopefully I can develop some new tools that help my organization. I've gotten some good integrations going already with Survey123 and the Cityworks API using Python. Instead of 'polling' for new Survey123 submissions with Windows Task running a python script on some recurring interval of minutes, I'd rather use a webhook to parse and process Survey123 submissions into service requests using Power Automate, which will happen virtually immediately, for every submission.

 

I'm just posting this for posterity since I had to get help with the proper Authorization header syntax for passing a token for API calls. Maybe this will save someone else some headache. This is a Power Automate cloud flow, manually triggered here for testing, but the input could be all kinds of stuff such as a webhook with values from a Survey123 form submission, which is my own priority use case. Note that Power Automate HTTP actions (the green one) require a premium level Power Automate license.

 

Here's the overall summary of my quick proof of concept. The red wrapper ('get cw token') is just an optional Scope which can be used to organize a Flow.

"image.png"Here's the format for getting the token initially. The HTTP action is specifying the POST method. The URI here is the General/Authentication/Authenticate method and passing in a LoginName and Password for a user that has the Cityworks API license(s) assigned.

 

I stored the LoginName and Password in a Compose instead of initializing a Variable. This seems simpler. Also, FYI you can't initialize variables inside Scopes; variables have to be declared outside of a Scope wrapper. Anyway... the Queries key here is data and the value is the JSON containing the LoginName and Password from the Compose I named 'cw api credentials'

 

"image"Here is what the Power Automate 'raw input' for the Authenticate method looks like when it is run:

"image" 

and the 'raw output' response from the Cityworks server:

"image" 

Next up is the Parse JSON action, using the response Body of the Authenticate method. Once I ran the Authenticate successfully the first time, I could use the raw output to 'Generate from sample' and populate the schema for this to Parse.

"image" 

{

    "type": "object",

    "properties": {

        "Value": {

            "type": "object",

            "properties": {

                "Token": {

                    "type": "string"

                }

            }

        },

        "Status": {

            "type": "integer"

        },

        "Message": {},

        "ErrorMessages": {

            "type": "array"

        },

        "WarningMessages": {

            "type": "array"

        },

        "SuccessMessages": {

            "type": "array"

        }

    }

}

 

This enables me to use the parsed Token string value in following Flow actions. I can imagine there is a better/simpler way to parse this string out but this seemed straightforward for testing.

 

Next is the tingly magical feeling I get from making something happen. I'm creating a new service request using a junk test template. You can find the Service Request Template Id of your templates in Admin Work Activity Templates menu. To create a service request using the API, the only required field to create is ProblemSid. The full list of values you can populate are in the API documentation at https://<yourdomain>/<site>/apidocs

 

Here I created another Compose action to write out the JSON for the service request values I want to pass to the Ams/ServiceRequest/Create method. My template's Id is 107. I threw in a string for "Details" as a proof of concept to see something else in the raw output.

 

What I got stuck on initially was how to pass the token for this method (and probably most other methods I will use). For Cityworks 23.10 at least you will use the Header key of Authorization and the value is the word Cityworks followed by a space, and then the raw Token string, which I'm pulling from the Parse JSON action I did above:

"image" 

The raw inputs when run:

"image" 

And raw outputs of the response from the Cityworks server. Everything here are the defaults of a new service request for this template except "Details" field, which I passed a value for.

"image" 

Quick side note on the optional token Validate method -- I did that for troubleshooting, just to make sure the token was accepted: The correct syntax here is to pass the {"Token":<tokenstring>} JSON object as the Queries data value, and not the raw token string by itself as the value. That confused me for a bit because I made an assumption, before paying closer attention to the API documentation.

 

"image"The response from this (if valid) is

{

  "Value": true,

  "Status": 0,

  "Message": null,

  "ErrorMessages": [],

  "WarningMessages": [],

  "SuccessMessages": []

}

    5 replies

    Known Participant
    Oct 2, 2025 4:10 PM UTC

    You're welcome! Glad to hear it was helpful. If this is also helpful to anyone else, here are some additional flow steps that I landed on for Survey123 ingestions into Cityworks.

     

    "image"A few other quirks I needed to figure out:

    • convert ArcGIS Online epoch millisecond datetime to input into EST
      • You can do this via a compose of variable in one stroke with
      • convertTimeZone(addSeconds('1970-1-1', <source of epoch ms time here>, 1000), 'MM/dd/yyyy hh:mm:ss tt'), 'UTC', 'Eastern Standard Time', 'MM/dd/yyyy hh:mm:ss tt')
    • convert ArcGIS Online wkid 4326 point geometry to wkid 3857 for Cityworks XY using an HTTP POST method (premium license needed) with ArcGIS Online geometry service to 'project' a geometry and parse geometry response for X and Y
      • "image"
    • Update the certain attributes of the Survey123 record as 'Received' and also some other info like the RequestId created and flow run URL and time ingested, using the ArcGIS Online connector
      • "image"
    • And then uploading the attachments to the ingested Cityworks service request as well. This was tricky but I finally figured it out.
      • "image"
      • "image"
    • Lastly a good practice to set up a 'fail' email to notify if something goes wrong

     

    Translate
    New Participant
    Oct 2, 2025 4:10 PM UTC

    @calvin harmin? , Just wanted to say thanks for this! I was in the same boat; mostly polling python scripts. I also found myself stuck on the authentication part. Using the 'compose' action that you suggested worked like a charm.

     

    I know this post took some effort on your part. So just wanted to say thanks! It saved me a lot of frustration.

    Translate
    New Participant
    Oct 2, 2025 4:11 PM UTC

    This is helpful we have been trying to get our IT department to provision us a power automate environment to do this same thing basically nice to know that others have done this. Did this require premium connectors in power automate?

     

    Translate
    Known Participant
    Oct 2, 2025 4:11 PM UTC

    This is helpful we have been trying to get our IT department to provision us a power automate environment to do this same thing basically nice to know that others have done this. Did this require premium connectors in power automate?

     

    @nick hetrick? Hi Nick, the HTTP actions (i.e. any Cityworks API calls) do require premium, and also if you want to use the ArcGIS Online or ArcGIS Enterprise connectors/actions. However, the Survey123 trigger itself (i.e. when a new form submission comes in) does not require a premium license.

    Translate
    New Participant
    Oct 2, 2025 4:12 PM UTC

    This is great documentation Calvin, thank you!

    Translate