Workforce Ready REST API Overview
What is REST? Web Services to Send & Receive Data Architecture style, platform & language independent, light weight alternative to SOAP Uses HTTP to post (send), get (read), put (change), and delete data “In many ways, the World Wide Web itself, based on HTTP, can be viewed as a REST-based architecture”
Why REST? Interface development 3rd party application development Custom data reporting Workforce Ready’s next gen mobile app will be developed using REST APIs only
FAQ: “Does this replace Middleware?”…No REST API FAQ: “Does this replace Middleware?”…No Middleware Windows Services SOAP APIs Pre-written SOAP scripts GUI-based interaction Regularly scheduled imports / exports Legacy API Architecture
Before getting started… Ensure you’ve added Web Services (REST) to your company marketplace (note – if you do not see the marketplace items then you do not have sufficient security privileges and will need to contact your manager) http://secure3.saashr.com/ta/do cs/rest/ should be referenced with the most up-to-date links and information
Authentication You’ll need a Token to make use of REST APIs Step 1 Authentication You’ll need a Token to make use of REST APIs Tokens can be secured with post invocation https://secure3.saashr.com:443/ta/rest/v1/login with a valid company, username, and password You will need to manually prefix your retrieved Token with “Bearer ” for all invocations thereafter *Note – full list of invocations are made public at https://secure3.saashr.com/ta/docs/rest/api.html
Quick Exercise… Request a Token… Encode your Workforce Ready password using http://www.url- encode-decode.com/ (note: http does not like special characters ) Open your internet browser and type in the following URL, using your unique login credentials: https://secure.saashr.com/ta/rest/v1/login?company=KronosWFRAdm in&username=[UserName]&password=[EncodedPassword] * e.g.: Company Short Name = KronosWFRAdmin; Username = TestEE; Password: Kronos#1 https://secure.saashr.com/ta/rest/v1/login?company=KRONOSWFRADMIN&username=TESTEE&password=KRONOS%231
Quick Exercise… Request a Token… If you got a response like this, you’re officially a REST API user! {"token":"c19f226d-c48c-4ecd-9beb-01c93831ee4f","ttl":3600000,"units":"milliseconds"} This response is written in language “JSON”, note the extra detail “ttl”, telling us we have one hour until this token expires
Authenticate by sending user credentials C# Example var client = new RestClient("https://middleware.workforceready.euta/rest/v1/login"); var request = new RestRequest(Method.POST); request.AddHeader("cache-control", "no-cache"); request.AddHeader("x-forwarded-proto", "https"); request.AddHeader("content-type", "application/json"); request.AddHeader("accept", "application/json"); request.AddParameter("application/json", "{\n \"credentials\": {\n \"username\": \" AUSERNAME \",\n \"password\": \" APASSWORD\ ",\n \"company\": \"admin\"\n }\n}\n", ParameterType.RequestBody); IRestResponse response = client.Execute(request) Authenticate by sending user credentials
Authentication > Invocation Step 2 Authentication > Invocation An invocation is the type of request you wish to make There are approximately 50 invocations available with base URL http://secure3.saashr.com/ta/docs/rest/, e.g.: …/employee/schedules …/report/saved/{settings_id} …/webclock *Note – full list of invocations are made public at http://secure3.saashr.com/ta/docs/rest/
Examples Authentication (i.e. token) Parameters of a REST API Invocation Examples Authentication (i.e. token) Content-Type (e.g. CSV, Text, XML, JSON) Content-ID (e.g. report, export, settings) Filter (i.e. field names)
Retrieve Saved Reports with Parameters Sub getAvailableReports() // declare variables Set myrequest = CreateObject("winhttp.winhttprequest.5.1") URLReport = ("https://secure.saashr.com:443/ta/rest/v1/reports?type=Saved&company%3shortna me=" & Company) myrequest.Open "GET", URLReport, False myrequest.setRequestHeader "Accept", "application/json" myrequest.setRequestHeader "Authentication", "Bearer " & Token myrequest.setRequestHeader "Content-Type", "application/json" myrequest.Send // handle response from myrequest.responsetext End Sub Excel VBA Example Retrieve Saved Reports with Parameters
FAQ: “Where do I find a specific {content_id}?” There are a few dynamic content-ID types: Export/{data_export_id} Import/{type ID} Report/../{report_ID} Report/../Saved/{settings_id} Each of which has a separate get request to retrieve the content-id needed: GET https://secure3.saashr.com:443/ta/rest/v1/exports GET https://secure3.saashr.com:443/ta/rest/v1/imports GET https://secure3.saashr.com:443/ta/rest/v1/reports GET https://secure3.saashr.com:443/ta/rest/v1/reports* * Note – saved reports must be specified in the Body as ‘typeSaved’ (not typeAll)
FAQ: “Where do I find a specific {content_id}?” Continued… You can also find the {content_id} within Workforce Ready under column title: “SYSTEM ID”
FAQ: “Where do I find a specific {content_id}?” Continued… Saved Reports Global Reports Dynamic settings_ids (unique for every saved report) Fixed report_ids (examples below): "REPORT_ACCOUNT_MY_TODO” "REPORT_COMPANY_ACCRUAL_BALANCES” "REPORT_EMPLOYEE_ROSTER” "REPORT_FIND_CC_1” "REPORT_MY_SAVED_REPORTS” Etc…(Full List in Appendix)
Examples GET: n/a POST: Body (JSON, XML, Multi-Part Form) Additional Requirements for Post, Put, and Delete Invocations Examples GET: n/a POST: Body (JSON, XML, Multi-Part Form) PUT: Body (JSON, XML, Multi-Part Form) DELETE: Filter (e.g. field name and operators)
Create Employee Base Compensation var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu:443/ta/rest/v1/employee/compensation/history", "method": "POST", "headers": { "authentication": "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d", "x-forwarded-proto": "https", "content-type": "application/json", "cache-control": "no-cache" }, "processData": false, "data": "{\r\n \"compensations\": [\r\n {\r\n \"company\" : {\r\n \"short_name\" : \"intl.demo\"\r\n }, \r\n \"employee\": {\r\n \"employee_id\": \"12335_546\"\r\n }, \r\n \"effective_from\": \"2016-7-1\",\r\n \"amount\": 5000.0,\r\n \"amount_period\": \"Month\",\r\n \"hours\": \"40:00\",\r\n …. ]\r\n}" } $.ajax(settings).done(function (response) { console.log(response); }); Javascript Example Create Employee Base Compensation
Authentication > Invocation > Response Handling Step 3 All REST API queries that reach our server will solicit a response { "ttl": 3600000, "token": "7bd0fd3b-ecba-4674-8b11- 39c51b38d820", "units": "milliseconds“ } …sometimes that response is not what you’d hoped for { "errors": [ { "code": 400, "message": "Unparsable payload" } ] } *Note – full list of invocations are made public at http://secure3.saashr.com/ta/docs/rest/
Response Handling (Continued) Response formats default to JSON, however WFR supports representations as XML, and in some cases CSV or HTML Error troubleshooting should start with the “code” and “message” provided in the response – usually the message is descriptive enough to get you what you need
Troubleshooting from WFR Once enabled you can audit all REST Invocations from within WFR
Important Note! API Removal Process Per Kronos engineering, APIs / invocations will be removed as required Depreciate the existing API Note in the documentation http://secure3.saashr.com/ta/docs/rest/ Mention in release notes Depreciated header on the response ~6-12 months later Notice of pending removal in release notes Following release Removal of API
Custom Web Clock Demonstration Explain excel configuration Run w/o timesheet profile, with bulk timesheet profile, with start/end timesheet profile, and again with start/end timesheet profile Confirm time entries in WFR Review REST Invocations within WFR
What is expected? Consultants are not expected to be able to write code/programs Consultants are expected to understand the framework and benefits of REST APIs
Homework Practice making REST API calls & reference our available resources from our test tool: http://secure3.saashr.com/ta/docs/rest/ Learn how JSON works: http://json-schema.org/example1.html Practice making advanced REST API calls using google chrome add-on “Postman”: Link …Imagine the possibilities!
Appendix
Login Examples Login Javascript (ajax) C# (RestSharp) cURL var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu/ta/rest/v1/login", "method": "POST", "headers": { "accept": "application/json", "content-type": "application/json", "x-forwarded-proto": "https", "cache-control": "no-cache" }, "processData": false, "data": "{\n \"credentials\": {\n \"username\": \"AUSERNAME\",\n \"password\": \"APASSWORD",\n \"company\": \"admin\"\n }\n}\n" } $.ajax(settings).done(function (response) { console.log(response); }); var client = new RestClient("https://middleware.workforceready.euta/rest/v1/login"); var request = new RestRequest(Method.POST); request.AddHeader("cache-control", "no-cache"); request.AddHeader("x-forwarded-proto", "https"); request.AddHeader("content-type", "application/json"); request.AddHeader("accept", "application/json"); request.AddParameter("application/json", "{\n \"credentials\": {\n \"username\": \" AUSERNAME \",\n \"password\": \" APASSWORD\ ",\n \"company\": \"admin\"\n }\n}\n", ParameterType.RequestBody); IRestResponse response = client.Execute(request); curl -X POST -H "Accept: application/json" -H "Content-Type: application/json" -H "X-FORWARDED-PROTO: https" -H "Cache-Control: no-cache" -d '{ "credentials": { "username": " AUSERNAME ", "password": " APASSWORD ", "company": "admin" } ' "https://middleware.workforceready.eu/ta/rest/v1/login"
List Available Reports Examples List Available Reports List available reports Javascript (ajax) C# (RestSharp) cURL var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu:443/ta/rest/v1/reports?type=all", "method": "GET", "headers": { "accept": "application/json", "authentication": "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d", "cache-control": "no-cache" } } $.ajax(settings).done(function (response) { console.log(response); }); var client = new RestClient("https://middleware.workforceready.eu:443/ta/rest/v1/reports?type=all"); var request = new RestRequest(Method.GET); request.AddHeader("cache-control", "no-cache"); request.AddHeader("authentication", "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d"); request.AddHeader("accept", "application/json"); IRestResponse response = client.Execute(request); curl -X GET -H "Accept: application/json" -H "Authentication: bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d" -H "Cache-Control: no-cache" "https://middleware.workforceready.eu/ta/rest/v1/reports?type=all"
Run Default Report Examples Run Default Report Javascript (ajax) C# (RestSharp) cURL var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu/ta/rest/v1/report/global/ADMIN_REPORT_SYSTEM_ACCOUNTS", "method": "GET", "headers": { "accept": "text/csv", "authentication": "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d", "cache-control": "no-cache" } } $.ajax(settings).done(function (response) { console.log(response); }); var client = new RestClient("https://middleware.workforceready.eu/ta/rest/v1/report/global/ADMIN_REPORT_SYSTEM_ACCOUNTS"); var request = new RestRequest(Method.GET); request.AddHeader("cache-control", "no-cache"); request.AddHeader("authentication", "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d"); request.AddHeader("accept", "text/csv"); IRestResponse response = client.Execute(request); curl -X GET -H "Accept: text/csv" -H "Authentication: bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d" -H "Cache-Control: no-cache" "https://middleware.workforceready.eu/ta/rest/v1/report/global/ADMIN_REPORT_SYSTEM_ACCOUNTS"
Run Saved Report Examples Run Saved Report Javascript (ajax) C# (RestSharp) cURL var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu/ta/rest/v1/report/saved/616257", "method": "GET", "headers": { "accept": "application/xml", "authentication": "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d", "cache-control": "no-cache" } } $.ajax(settings).done(function (response) { console.log(response); }); var client = new RestClient("https://middleware.workforceready.eu/ta/rest/v1/report/saved/616257"); var request = new RestRequest(Method.GET); request.AddHeader("cache-control", "no-cache"); request.AddHeader("authentication", "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d"); request.AddHeader("accept", "application/xml"); IRestResponse response = client.Execute(request); curl -X GET -H "Accept: application/xml" -H "Authentication: bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d" -H "Cache-Control: no-cache" "https://middleware.workforceready.eu/ta/rest/v1/report/saved/616257"
Create Employee Base Compensation Examples Create Employee Base Compensation Create Employee Base Compensation Javascript (ajax) C# (RestSharp) cURL var settings = { "async": true, "crossDomain": true, "url": "https://middleware.workforceready.eu:443/ta/rest/v1/employee/compensation/history", "method": "POST", "headers": { "authentication": "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d", "x-forwarded-proto": "https", "content-type": "application/json", "cache-control": "no-cache" }, "processData": false, "data": "{\r\n \"compensations\": [\r\n {\r\n \"company\" : {\r\n \"short_name\" : \"intl.demo\"\r\n }, \r\n \"employee\": {\r\n \"employee_id\": \"12335_546\"\r\n }, \r\n \"effective_from\": \"2016-7-1\",\r\n \"amount\": 5000.0,\r\n \"amount_period\": \"Month\",\r\n \"hours\": \"40:00\",\r\n \"hours_period\": \"Month\",\r\n \"num_pp_in_year\": 52, \r\n \"remove_all_future\": true\r\n },\r\n {\r\n \"company\" : {\r\n \"short_name\" : \"intl.demo\"\r\n }, \r\n \"employee\": {\r\n \"employee_id\": \"12335_546\"\r\n }, \r\n \"effective_from\": \"2017-7-1\",\r\n \"amount\": 5000.0,\r\n \"amount_period\": \"Month\",\r\n \"hours\": \"40:00\",\r\n \"hours_period\": \"Month\",\r\n \"num_pp_in_year\": 52, \r\n \"remove_all_future\": false\r\n }\r\n ]\r\n}" } $.ajax(settings).done(function (response) { console.log(response); }); var client = new RestClient("https://middleware.workforceready.eu:443/ta/rest/v1/employee/compensation/history"); var request = new RestRequest(Method.POST); request.AddHeader("cache-control", "no-cache"); request.AddHeader("content-type", "application/json"); request.AddHeader("x-forwarded-proto", "https"); request.AddHeader("authentication", "bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d"); request.AddParameter("application/json", "{\r\n \"compensations\": [\r\n {\r\n \"company\" : {\r\n \"short_name\" : \"intl.demo\"\r\n }, \r\n \"employee\": {\r\n \"employee_id\": \"12335_546\"\r\n }, \r\n \"effective_from\": \"2016-7-1\",\r\n \"amount\": 5000.0,\r\n \"amount_period\": \"Month\",\r\n \"hours\": \"40:00\",\r\n \"hours_period\": \"Month\",\r\n \"num_pp_in_year\": 52, \r\n \"remove_all_future\": true\r\n },\r\n {\r\n \"company\" : {\r\n \"short_name\" : \"intl.demo\"\r\n }, \r\n \"employee\": {\r\n \"employee_id\": \"12335_546\"\r\n }, \r\n \"effective_from\": \"2017-7-1\",\r\n \"amount\": 5000.0,\r\n \"amount_period\": \"Month\",\r\n \"hours\": \"40:00\",\r\n \"hours_period\": \"Month\",\r\n \"num_pp_in_year\": 52, \r\n \"remove_all_future\": false\r\n }\r\n ]\r\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); curl -X POST -H "Authentication: bearer 23bf5de4-298d-43f5-ae82-354a99a9d71d" -H "X-FORWARDED-PROTO: https" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ "compensations": [ { "company" : { "short_name" : "intl.demo" }, "employee": { "employee_id": "12335_546" }, "effective_from": "2016-7-1", "amount": 5000.0, "amount_period": "Month", "hours": "40:00", "hours_period": "Month", "num_pp_in_year": 52, "remove_all_future": true }, { "effective_from": "2017-7-1", "remove_all_future": false } ] }' "https://middleware.workforceready.eu/ta/rest/v1/employee/compensation/history"
Global Reports Available Report_ids "ReportIds": [ "REPORT_ACCOUNT_MY_TODO", "REPORT_ALL_ACCOUNT_NOTES", "REPORT_ALL_SYSTEM_ACCOUNTS", "REPORT_ALL_TIME_ENTRIES", "REPORT_ANNIVERSARY_CALENDAR_COMPANY", "REPORT_ANNIVERSARY_CALENDAR_COMPANY_MONTHLY", "REPORT_ANNIVERSARY_CALENDAR_COMPANY_WEEKLY", "REPORT_APPLICANT_CUSTOM_FORM_ITEMS", "REPORT_APPLICANT_MY_CUSTOM_FORM_ITEMS", "REPORT_APPROVE_EXTRA_PAY_ENTRIES", "REPORT_APPROVE_TIME_ENTRIES", "REPORT_BIRTHDAY_CALENDAR_COMPANY", "REPORT_BIRTHDAY_CALENDAR_COMPANY_MONTHLY", "REPORT_COMPANY_ACCRUAL_BALANCES", "REPORT_COMPANY_ACCRUAL_BALANCES_AS_OF_DATE", "REPORT_COMPANY_ACCRUAL_HISTORY", "REPORT_COMPANY_EXCEPTION_BY_ENTRY" "REPORT_COMPANY_EXCEPTION_SUMMARY_BY_WEEK", "REPORT_COMPANY_SKILLS_PULL", "REPORT_EMPLOYEE_CUSTOM_FORM_ITEMS", "REPORT_EMPLOYEE_HARDWARE_SETTINGS", "REPORT_EMPLOYEE_MY_CUSTOM_FORM_ITEMS", "REPORT_EMPLOYEE_ROSTER", "REPORT_EMPLOYEE_SENIORITY", "REPORT_EMPLOYEE_SUMMARY", "REPORT_EMPLOYEE_TIMESHEETS", "REPORT_EMPLOYEES_POINTS_BALANCES", "REPORT_EMPLOYEES_POINTS_DETAILS", "REPORT_EMPLOYEES_POINTS_HISTORY", "REPORT_FIND_CC_1", "REPORT_FIND_CC_2", "REPORT_FIND_CC_3", "REPORT_FIND_CC_4", "REPORT_FIND_CC_5", "REPORT_FIND_CC_6", "REPORT_FIND_CC_7",
Global Reports (Continued) Available Report_ids Global Reports (Continued) "REPORT_FIND_CC_8", "REPORT_FIND_CC_9", "REPORT_HR_ACTION_REQUESTS", "REPORT_HR_EMPLOYEE_INVENTORY_ITEMS", "REPORT_HR_MY_EMPLOYEE_INVENTORY_ITEMS", "REPORT_LATE_EARLY_ABSENT", "REPORT_MY_SAVED_REPORTS", "REPORT_PERFORMANCE_REVIEWS", "REPORT_PTO_REQUEST_ALL", "REPORT_PTO_REQUEST_HISTORY", "REPORT_PTO_REQUEST_MY_TO_APPROVE", "REPORT_PTO_REQUEST_OPEN", "REPORT_TIME_DOT_BOARD", "REPORT_TIME_ENTRY_BY_COST_CENTER", "REPORT_TIME_ENTRY_BY_DAY", "REPORT_TIME_ENTRY_BY_EMPLOYEE", "REPORT_TIME_ENTRY_BY_WEEK", "REPORT_TIME_ENTRY_DETAILED", "REPORT_TIME_ENTRY_DETAILED_OVERVIEW", "REPORT_TIME_ENTRY_DETAILED_OVERVIEW_PDF", "REPORT_TIME_ENTRY_SUMMARY", "REPORT_TIME_OFF_CALENDAR_COMPANY", "REPORT_TIME_OFF_CALENDAR_COMPANY_MONTHLY", "REPORT_TIME_OFF_CALENDAR_COMPANY_WEEKLY", "REPORT_TIME_SUMMARY_BY_WEEK", "REPORT_TIMESHEET_APPROVAL_HIST_OVERVIEW", "REPORT_TIMESHEET_VIEW_ALL", "REPORT_TIMESHEET_VIEW_ALL_DOCUMENTS", "REPORT_TIMESHEET_VIEW_ALL_NOTES", "REPORT_TIMESHEET_VIEW_PAY_PERIOD", "REPORT_TIMESHEET_VIEW_WEEK", "REPORT_TIMESHEETS_ALL_CURRENT", "REPORT_TIMESHEETS_ALL_OPEN", "REPORT_TIMESHEETS_MY_APPROVE", "REPORT_TREE_CC_1", "REPORT_TREE_CC_2", "REPORT_TREE_CC_3", "REPORT_TREE_CC_4",
Global Reports (Continued) Available Report_ids Global Reports (Continued) "REPORT_TREE_CC_5", "REPORT_TREE_CC_6", "REPORT_TREE_CC_7", "REPORT_TREE_CC_8", "REPORT_TREE_CC_9", "REPORT_TREE_TIME_OFF", "REPORT_WORK_SCHEDULE_BUDGET_VS_ACTUAL", "REPORT_WORK_SCHEDULE_DAY", "REPORT_WORK_SCHEDULE_ENTRIES", "REPORT_WORK_SCHEDULE_ENTRIES_EDIT", "REPORT_WORK_SCHEDULE_OVERVIEW_MONTHLY", "REPORT_WORK_SCHEDULE_OVERVIEW_WEEKLY", "REPORT_WORK_SCHEDULE_WEEK", "REPORT_WORK_SCHEDULE_WEEK_BY_DAILY_SCHEDULE" ] }