Skip to main content

logoCorrectSize.png

Workday Adaptive Planning Knowledge Center

Making Adaptive Planning API Requests with Workday Credentials

Describes how to make Adaptive Planning API Requests with Workday Credentials

Some links in this article go to the Workday community. If you don't have a community account, request one.

Workday-synchronized users who log in to Workday and use the Adaptive Insights Worklet can run Adaptive Insights public APIs.  Users must create an ISU specifically for making these API requests. These users must provide a token in the credentials element of Adaptive Insights API requests instead of a username and password. You can cache this token and use it until it expires. After it expires, you must get a new token.

Before You Begin

Workday Domain and Security Groups

  •  Verify the ISU users who need API access are part of the Set Up: Adaptive Insights API Access security domain.

Workday Setup Tasks

  • Verify that Single Sign-On tasks are enabled within the User Sign-on tab in the Adaptive Insights tab.
  • Verify the Public API setup task is enabled within the Public API tab in the Adaptive Insights tab.
  • Verify an integration system user (ISU) setup task created an ISU specifically for making Workday Adaptive Planning API requests and mapped it to an Adaptive Insights user account.

Adaptive Insights User Admin

  • Verify you see the ISU beginning with PublicAPIISU_  in the users list within Administration > Users.
  • Verify this user has the level access needed for the APIs they want to run. New ISUs don't receive level access by default.

Basic Steps

  1. Get a Certificate and Extract your Public Key.
  2. Register an API Client in Workday with that certificate.
  3. Generate a JWT Token, Retrieve Workday access_token, and Retrieve AdaptiveAPIAccessToken.
  4. Use the AdaptiveAPIAccessToken in an Adaptive Insights API Request.

Get a Certificate and Extract your Public Key

You can create a certificate yourself or purchase a certificate from a well-known certificate authority. For the details on the parameters needed for your X.509 Certificate in Workday, see Concept: X.509 Certificates in Workday.

  1. Extract the public key from your certificate for uploading to Workday.
  2. Retain your private key for use in your calling application.
  3. Paste the certificate into Workday when registering your JWT bearer token. Reference your private key in your script.

See OAuth with JWT (JSON Web Token) and Access External Endpoints.

Register a Workday API Client

  1. Register an API Client with Client Grant Type: Jwt Bearer Grant in Workday. See Register an API Client for more information.
  2. Copy the public key derived for your certificate into the x.509 Certificate in the Register API Client page in Workday.
  3. For Scope (Functional Area) select Adaptive Insights.
  4. For Redirection URL enter https://workday.com
  5. When you finish registering the API client, copy the resulting fields at the bottom of the page to a text file to use later.
    • Workday REST API Endpoint
    • Token Endpoint
    • Authorization Endpoint

Generate JWT Token, Retrieve Workday access_token, and Retrieve AdaptiveAPIAccessToken

  1. Use your private key and generate the JWT token by running pseudo code listed below.
  2. To retrieve a Workday access token, make a POST request to the Token Endpoint, passing grant_type and assertion. Use the Token Endpoint copied after registering your API client in Workday.

    Example Token Endpoint:
https://i-0b73e720dd1d2a041.workdaysuv.com/ccx/oauth2/super/token

     Example CURL request to the Token Endpoint

curl --request POST 'https://i-0b73e720dd1d2a041.workdaysuv.com/ccx/oauth2/super/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode 'assertion={{the jwt assertion from your certificate}}'
  1. Retrieve the AdaptiveAPIAccessToken by calling the Workday endpoint using the Workday access token. Use the prior access_token value as the Bearer token in the Auth header for this GET.
    Example Access Token:
https://i-0b73e720dd1d2a041.workdaysuv.com/ccx/api/planning/v1/super/adaptiveAPIAccessToken

     Example CURL request for the AdaptiveAPIAccessToken:

 curl --request GET 'https://i-0b73e720dd1d2a041.workdaysuv.com/ccx/api/planning/v1/super/adaptiveAPIAccessToken' \
--header 'Authorization: Bearer {{JWT Bearer Token access_token you get back from the Token Endpoint request in the previous step}}' \
--data-raw ''
  1. Call the Adaptive Insights API using the AdaptiveAPIAccessToken in the credentials element of the XML in an HTTP POST
    Example:
curl -H "Content-Type: text/xml" -d '<?xml version='1.0' encoding='UTF-8'?><call method="exportLevels" callerName="a string that identifies your client application"><credentials token="ID eyJhbDci0iJSUzUxMiIsUmtpZCI6IdvcmtkYXlfa2V5In0.eyJpc3KiOiJXb3JrZGFZIiwiYXV0aF90aW1lIjoxNTczMTY3NjU2LBjzeXnfynnJd.bztQzBmHeTj1amnHA-r96TdrJK0MXMghUFF1KyjxqIq6ruHU63dJp3JAJn3Eche7SEcoZBVGX4wJgna106pmCqgrrVWMf13Hg_sb_szabal2XN1KEEk1qh8z1IDlbt6qJIL_xyW3J2nNSs5ima3vJUYU5sRQXwXst0GuFWXpy464GyB4oKcscrg28X3dnPO_ytdohMKHsWkqyHQKXFQwoQezFaGy10sp4RRUj0lpOZX8C9oBHDYA58IXxGkqKLJVNPvDND6rGY5fTHQ-yxpe1nz-WqB0boiq9a-dv8b3EBzbelxj2fCPdMbng6kzygDcA2at_7BNQiyzfIovS5AG"/><include versionID="3" inaccessibleValues="false"/><sheet id="3" /></call>' -X POST https://api.adaptiveplanning.com/api/v23

Sample Java Application for Generating a JWT Token

This sample Java application generates a JWT token.

//**********************************************************************
//
// File: TestPublicAPISample.java
//
// Copyright 2004-2019 Adaptive Insights LLC, a Workday company.
// All Rights Reserved.
//
// This work contains trade secrets and confidential material of
// Adaptive Insights LLC, a Workday company and its use or disclosure in whole or in part
// without the express written permission of Adaptive Insights LLC, a Workday company is prohibited.
//
//**********************************************************************



import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.text.MessageFormat;
//import java.util.Base64;

import org.apache.commons.codec.binary.Base64;



    public class AccessAdaptiveAPI
    {
        public static void main(String args[])
        {
            String jwtKeyStoreFileString = "/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/security/JWTkeystore.jks";
            String clientIDString = "BlywNDM1NmMtZTk2Mi00NTZiTWEyZjktZWM1NGJiOGQ3Yjca";
            String userIdString = "PublicAPIISU_Test";
            
            System.out.println(GetAccessToken(clientIDString,userIdString,jwtKeyStoreFileString));
        }
        
        public void callAPI()
        {
            
        }
        
        public String getAdaptiveAPIToken()
        {    
            return "";
        }
        
        public String getJWTToken(String privateKey, String username)
        {    
            return "";
        }
        
        public void callWorkdayAPI()
        {
            
            
        }
        
        public static String GetAccessToken(String clientId, String userId, String jwtKeyStore) {

            String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
            String claimTemplate = "'{'\"iss\": \"{0}\", \"sub\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\"'}'";


            try {
                StringBuffer token = new StringBuffer();

                //Encode the JWT Header and add it to our string to sign
                token.append(Base64.encodeBase64URLSafeString(header.getBytes("UTF-8")));

                //Separate with a period
                token.append(".");


                //Create the JWT Claims Object
                String[] claimArray = new String[4];
                //iss
                claimArray[0] = clientId;
                //sub
                claimArray[1] = userId;
                //aud
                claimArray[2] = "wd";
                //exp
                claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
                MessageFormat claims;
                claims = new MessageFormat(claimTemplate);
                String payload = claims.format(claimArray);

                //Add the encoded claims object
                token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));
                //token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));

                //Load the private key from a keystore
                KeyStore keystore = KeyStore.getInstance("JKS");
                keystore.load(new FileInputStream(jwtKeyStore), "Workday123!".toCharArray());
                PrivateKey privateKey = (PrivateKey) keystore.getKey("Workday", "Workday123!".toCharArray());

                //Sign the JWT Header + "." + JWT Claims Object
                Signature signature = Signature.getInstance("SHA256withRSA");
                signature.initSign(privateKey);
                signature.update(token.toString().getBytes("UTF-8"));
                String signedPayload = Base64.encodeBase64URLSafeString(signature.sign());

                //Separate with a period
                token.append(".");

                //Add the encoded signature
                token.append(signedPayload);
                return token.toString();
                //System.out.println(token.toString());

            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
    }

Sample C# Application for Generating a JWT Token

This sample C# application generates a JWT token that replaces the username and password in the credentials element of an Adaptive Insights API request.

This sample code requires a NuGet page.
Required NuGet package: System.IdentityModel.Tokens.Jwt  

            var clientId = "BlywNDM1NmMtZTk2Mi00NTZiTWEyZjktZWM1NGJiOGQ3Yjca";//Client ID from workday API Client
            var isu = "PublicAPIISU_Test"; //the ISU 
            var timeout = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000 + 300).ToString(CultureInfo.InvariantCulture);
            var environment = "wd";
            var pfxFilePath = @"C:\temp\JWTkeystore2.pfx";
            var pfxPassword = "Workday123!";

            var payload = new JwtPayload
            {
                {"iss", clientId},
                {"sub", isu},
                {"aud", environment},
                {"exp", timeout },
            };

            var signingCredentials = new X509SigningCredentials(new X509Certificate2(pfxFilePath, pfxPassword), SecurityAlgorithms.RsaSha256); // the matching PKCS #12 file with private key
            var jwtHeader = new JwtHeader(signingCredentials);

            var secToken = new JwtSecurityToken(jwtHeader, payload);
            var handler = new JwtSecurityTokenHandler();
            var tokenToWorkday = handler.WriteToken(secToken);
            Console.WriteLine(tokenToWorkday);

Use the AdaptiveAPIAccessToken in an Adaptive Insights API Request

Once you set up Workday for Adaptive Insights public API access, the credentials element of Adaptive Insights API requests use the AdaptiveAPIAccessToken instead of a username and password. Basic authentication with username and password won't work. See Adaptive REST API and API Methods for more.

Example AdaptiveAPIAccessToken in an Adaptive Insights API Request

<?xml version='1.0' encoding='UTF-8'?>
<call method="exportLevels" callerName="a string that identifies your client application">
    <credentials token="ID eyJhbDci0iJSUzUxMiIsUmtpZCI6IdvcmtkYXlfa2V5In0.eyJpc3KiOiJXb3JrZGFZIiwiYXV0aF90aW1lIjoxNTczMTY3NjU2LBjzeXnfynnJd.bztQzBmHeTj1amnHA-r96TdrJK0MXMghUFF1KyjxqIq6ruHU63dJp3JAJn3Eche7SEcoZBVGX4wJgna106pmCqgrrVWMf13Hg_sb_szabal2XN1KEEk1qh8z1IDlbt6qJIL_xyW3J2nNSs5ima3vJUYU5sRQXwXst0GuFWXpy464GyB4oKcscrg28X3dnPO_ytdohMKHsWkqyHQKXFQwoQezFaGy10sp4RRUj0lpOZX8C9oBHDYA58IXxGkqKLJVNPvDND6rGY5fTHQ-yxpe1nz-WqB0boiq9a-dv8b3EBzbelxj2fCPdMbng6kzygDcA2at_7BNQiyzfIovS5AG"/>
    <include versionID="3" inaccessibleValues="false"/>
    <sheet id="3" />
</call>

 

  • Was this article helpful?