Bulk file upload to Workday

Screenshot of a power automate flow

One of the challenges for a smaller company is that the departments that deal in sensitive data - such as HR and payroll - don’t have their own dedicated in-house technology partners who are ‘inside the tent’ for data. The solution is to use a managed service provider who can provide tech savvy resource to help the department get their job done.

Of course, there are always projects that are too small for the MSP and too large for manual effort. An example last week was bulk uploading documents for employees to Workday HCM: there’s enough employees that manual upload would be tedious and error prone, yet few enough that having the MSP build a dedicated integration would be overkill.

In these scenarios I’ve found Power Automate (PA) to be a great tool: it can expose the power of APIs yet keeps itself simple enough that end-users can make it work for them.

Better still, Power Automate offers connectors for Workday. Unfortunately these connectors are in lousy shape: labelled as preview, they lack documentation, provide limited functions and have some bugs 1. Frankly, making them premium is an insult.

Happily they do provide a trap door: the SOAP Operation Action can, in theory, be used to call any Workday API2 you have permissions on, using the connection details stored in your PA account.

Here’s a simple Power Automate that loops through a OneDrive folder of PDF files, each named with the employee ID, and uploads them to the employees documents.

The first step is to connect to OneDrive and initialize a couple of variables to keep things easier to read later on. The flow itself is started on demand (trigger not shown).

OneDrive Connection

For the list of files, loop (see screenshot above) and for each file

In theory you can do that SOAP call using the HTTP connector: however you’d then have to hard code the SOAP header which is definitely less secure.

Post File

Here’s the raw request to save typing errors (essentially everything within the SOAP body). If you’re not controlling the variables, you’ll want to wrap them in a CDATA escape to prevent malformed XML errors (see footnote below). You’ll also need to figure out the Workday ID (XXX below) of the document category you’d like to send:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<bsvc:Put_Worker_Document_Request xmlns:bsvc="urn:com.workday/bsvc" bsvc:Add_Only="false" bsvc:version="v13">
  <bsvc:Worker_Document_Data>
    <bsvc:ID>@{variables('DocID')}</bsvc:ID>
     <bsvc:Filename>@{variables('DocID')}</bsvc:Filename>
     <bsvc:Comment>Your comment here</bsvc:Comment>
      <bsvc:File>@{variables('EncodedFileContent')}</bsvc:File>
      <bsvc:Worker_Document_Category_Reference bsvc:Descriptor="string">
        <bsvc:ID bsvc:type="WID">XXX</bsvc:ID>
      </bsvc:Worker_Document_Category_Reference>
      <bsvc:Worker_Reference bsvc:Descriptor="string">
          <bsvc:ID bsvc:type="Employee_ID">@{items('Apply_to_each')?['NameNoExt']}</bsvc:ID>
      </bsvc:Worker_Reference>
  </bsvc:Worker_Document_Data>
</bsvc:Put_Worker_Document_Request>

That’s it! I hope you find it useful.


  1. The worst of which is if your Workday username or password contains any of the five XML entities the SOAP call will fail with an ambiguous error because the XML is malformed. The simple fix would be to wrap these two parameters with a CDATA escape ↩︎

  2. Even though it’s SOAP the Workday API is very logical. Figure out how to make one call and the rest are easy. A post for another time. ↩︎