Skip to main content

Integration API

MindKey API is a REST API and it is hosted in Azure. Our API has predictable resource-oriented URLs, accepts JSON request bodies, returns JSON, and uses standard HTTP response codes, authentication and verbs.

API access prerequisites

  • Local certificate and API key provided by MindKey
  • List of IP numbers communicated by customers to our team
  • Optional: GitHub account(s) shared by customers to our team for the upcoming API demo samples.

Customers will get access to the most common parts of the data model through our API. Therefore, the samples that we provide facilitate the data reading from our data model.

Contact your primary consultant to receive more information on the local certificate and the API key. For additional information about the certificate, see Certificate renewal process.

Tools suggestions

  • Postman
  • PowerShell
  • Git

Authentication

The authentication process requires a certificate and an API key. MindKey generates a new certificate that can be used locally on the developer’s machine. Next, we provide an API key that adds an increased layer of security for customers. The API key uniquely identifies the database of the customers, and together with the certificate, they represent the authenticator.

Customers need to provide the list of IP numbers that will access the API.

info

We do not have customizable authentication for our API.

Integration samples and PowerShell module

You can request a Powershell or C# sample that illustrates how to use our API. The PowerShell samples use a so-called "shared" module developed internally by MindKey. The module can be supplied to customers and it helps to easily make requests to the MindKey API.

Quick start quide for your first request

The following PowerShell example describes how to obtain a list of employees in your MindKey.

info

Download the PowerShell modules from the integrations-shared repository to successfully complete the below steps.

In PowerShell, import the MindKeyRest module with:

Import-Module (PATH-TO- MindKey-Rest.psm1) -Force

Connect to the API using the Connect-MindKeyRest method provided by the module:

Connect-MindKeyRest “integration2.mindkey.com” -CertificateThumbprint THUMBPRINT -CustomerId CUSTOMERID
info

THUMBPRINT and CUSTOMERID are individual from one customer to another.

Next, you need to set up a request body by specifying which columns from the employee table you want to include. For more information on what columns are available and what else you can include in the post body, see the controllers section for how to get controller metadata.

$body = @{
columns = "EmployeeId, Name_FullName, ExternalReference, Address_Street, Address_ZipPostalCode, Address_City, Address_CountryRegion, SeniorityDate, PrivateMobilePhoneNumber_FullPhoneNumber, HomePhoneNumber_FullPhoneNumber, Email"
}

After this point, everything is in place to make your first request. To proceed, use the Invoke-MindKeyRestPost method, that is available in the ‘shared’ module.

$Employees = Invoke-MindKeyRestPost "employees/find" -InputObject $body

The employees variable now contains employee objects for every employee in your MindKey.

To try it out, you can write the names of all the employees as followed:

foreach($Employee in $Employees)
{
Employee.Name_FullName
}

For more examples in either Powershell or C#, check out the integration-samples repository.

CRUD operations

Create/Insert

controller_name/insert -InputObject $Object

$Object contains fields with values for the given controller. All fields on a given target controller need a value. Fields defined on target controller that are not assigned a value are updated with value equal $null.

The code below is an example of the INSERT command for a controller.

// FILE with definition of target controllers:
namespace NameSpaceTarget
{
public class ControllerInsertTarget
{
public string ControllerId { get; set; }
public string ControllerField1 { get; set; }
}
}
$Controller = New-Object NameSpaceTarget.ControllerInsertTarget
$Controller.ControllerId = "ControllerId"
$Controller.ControllerField1 = "Controller Field1 value"

try
{
$insertedController = Invoke-MindKeyRestPost "controllers/insert" -InputObject $Controller
}
catch
{
Add-Error "An critical error occurred while inserting controller: $($_.Exception)"
}

The $insertedController returns a full controller record with all fields from controller in MindKey.

Update

controller_name/update?Key=$KeyValue -InputObject $Object

$Object contains fields with values for the given controller. All fields on a given target controller need a value. Fields defined on target controller that are not assigned a value are updated with value equal $null.

The code snippet below shows an example for the UPDATE command for a controller.

// FILE with definition of target controllers:
namespace NameSpaceTarget
{
public class ControllerUpdateTarget
{
public string ControllerField1 { get; set; }
}
}
$Controller = New-Object NameSpaceTarget.ControllerUpdateTarget
$Controller.ControllerField1 = "Controller Field1 value update"

try
{
Invoke-MindKeyRestPost "controllers/update?ControllerId="+$controllerIdValue -InputObject $Controller
}
catch
{
Add-Error "An critical error occurred while updating controller: $($_.Exception)"
}

Delete

{{controller_name}}/delete?Key=$KeyValue

The DELETE command for a controller looks like demonstrated below:

try
{
Invoke-MindKeyRestPost "controllers/delete?ControllerId="+$controllerIdValue
}
catch
{
Add-Error "An critical error occurred while deleting controller: $($_.Exception)"
}

Write

{{controller_name}}/write?Key=$KeyValue -InputObject $Object

$Object contains fields with values for given controller. All fields on a given target controller need a value. Fields defined on target controller that are not assigned a value are updated with value equal $null.

The WRITE command either inserts or updates the given controller, depending if the key value exists or not.

The example below shows how the WRITE command for a controller looks like.

// FILE with definition of target controllers:
namespace NameSpaceTarget
{
public class ControllerWriteTarget
{
public string ControllerId { get; set; }
public string ControllerField1 { get; set; }
}
}
$Controller = New-Object NameSpaceTarget.ControllerWriteTarget
$Controller.ControllerId = "ControllerId"
$Controller.ControllerField1 = "Controller Field1 value"

try
{
Invoke-MindKeyRestPost "controllers/write?ControllerId="+$$Controller.ControllerId -InputObject $Controller
}
catch
{
Add-Error "An critical error occurred while writing controller: $($_.Exception)"
}

Find/Select/Read

try {
$ControllerId = 'controllerId'
Add-Info ("Find Controller: " + $ControllerId)

# Setup search condition
$body = @{
searchCondition = @(
@{
column = "ControllerId"
value = $ControllerId
}
)
}

$Result = Invoke-MindKeyRestPost "controllers/find" -InputObject $body

if (!$Result) {
Add-Info ("No Match for criteria: ControllerId = " + $ControllerId)
}
}
catch {
Add-Error "An critical error occurred while getting controller: $($_.Exception)"
}

Logic operators AND/OR and TransDate

Logical operators are used to change the default conditon AND to OR. If a logical operator is not given, the search condition is by default AND. Logical operators can either contain AND or OR. They cannot be used both in the same search condition.

Below you can find an example including logical operators:

$body = @{
columns = "ControllerId, Controller_Name"
searchCondition = @(
@{
column = "ControllerId"
value = $ControllerId1
},
@{
column = "ControllerId"
value = $ControllerId2
logicalOperator = "OR"
}
)
}

$Controllers = Invoke-MindKeyRestPost "controllers/find" -InputObject $body

Condition Operators

Condition operators are used to change the default condition EQUAL. If a conditional operator is not given, the search condition is by default EQUAL.

Conditional operators can have the values NOTEQUAL, LESS, GREATER, LESSOREQUAL, GREATEROREQUAL or LIKE.

$body = @{
columns = "ControllerId, Controller_Name"
searchCondition = @(
@{
column = "ControllerId"
value = "100"
conditionOperator = "NOTEQUAL"
}
)
}

$Controllers = Invoke-MindKeyRestPost "controllers/find" -InputObject $body

Employee Position Mode

You can add a position mode to pull connected positionVersions records of different types.

Without given a postionMode many positionVersion fields are available directly from the employee controller. The default join mode for this is CurrentOuterjoin. From the employee controller the fields can be picked by using their short names like OrganizationId, LocationId, etc.

Fields from postionVersion on the employee controller are fields for the actual date. If no positionVersion is present for employee on the actual date, these fields remain empty. To pick the correct positionVersion controller, positionMode can be added to the employee search.

There are four different modes that you can add:

  • positionMode = "CurrentOuterJoin". This mode returns all employees. If a positionVersion record is found, the fields from positionVersion are also returned.
  • positionMode = "CurrentInnerJoin". This mode returns employees, where a positionVersion record exists.
  • positionMode = "TerminatedInnerJoin". This mode returns terminated employees since a given date. TransDate is a mandatory customSearchCondition for this operation.
  • positionMode = "FutureInnerJoin". This mode returns employees with a future employment from a given date. TransDate is a mandatory customSearchCondition for this operation.

The positionColumns command needs to be assigned together with the positionMode. At the same time, you can enter here the fields to be picked from the positionVersion controller.

The customSearchCondition command needs to be used for TerminatedInnerJoin and FutureInnerJoin. Proceed by entering the date when the transctions should be selected. The syntax is as follows:

# Terminated or Future Employments since this date
"customSearchCondition" = @(
@{
condition = "TransDate"
value = "2019-07-01T00:00:00"
onlyParameter = $true
}
)

Fields returned from the positionVersion on the employee controller are for instance named $Employee.PositionVersion_Organizationid.

User defined fields

To retrieve attached columns for user defined fields on the employee record, add userDefinedColumns = "UserDefinedColumnName" to the employee search.

The userdefined fields returned on the employee controller receive for instance names like $Employee.UserDefinedColumn_UserDefinedColumnName.

info

Fields used in the API should not be renamed in MindKey. Renaming the fields causes the script to fail as the field name and selection will be wrong.

Integration Leave, Time Tracking, and Mileage

You can integrate leave and/or time-tracking by using the LeaveIntegration, timeTrackingIntegration, and mileageIntegration records. These records are created when leave, time-tracking, and mileage are approved in MindKey.

The records have status fields specific for an API integration. The status can have the following value:

  • 1 = ready (ready to "export" transaction)
  • 2 = found (export job has read the transaction)
  • 3 = updated (export has finished updating the transaction)

In this case, note the below observations:

  • When the API is running it should read all transactions with status 1 or status 2.
  • When starting the update job, all transactions with status equal to 1 should be updated to status = 2.
  • When export job is finished, all handled transactions should be update to 3.

Logging results to MindKey

Any integration can write to the System log that MindKey provides. MindKey users can use it to identify and be notified of eventual errors.

The endpoint for the log is POST syslogs/insert and the Powershell sample below is of an object that can be posted to the syslog. All the values in {{}} are to be replaced and the functions GetErrorCount and Get-WarningCount are from our Powershell module.

The code also illustrates 3 possible statuses where 1 means success, 2 means warning, and 3 means error.

We recommend the users of MindKey to set up notifications based on these statuses.

$SysLog.MessageText = {{Log_As_String}}
$SysLog.TransDateTime = {{Current_DateTIme}}
$SysLog.HostName = {{Machine_Name / Ip_Address}}
$SysLog.UserName = {{User_Running_Integration}}
$SysLog.JobName = {{Integration_Name}}
$SysLog.Application = 'MindKey Integration Service'

if (Get-ErrorCount -ge 1)
{
$SysLog.Status = 3
}
else
{
if (Get-WarningCount -ge 1)
{
$SysLog.Status = 2
}
else
{
$SysLog.Status = 1
}
}

Controllers

You can also obtain the entire list of controllers from the API. For that, call the following endpoint with a GET request in Postman or in the chosen tool:

{{api_root}}/{{customer_id}}/system/controllers
info
{{api_root}} = integration2.mindkey.com/api

More information about an individual controller can be obtained by calling:

{{api_root}}/{{customer_id}}/{{controller_name}}/metadata

This returns the data model for the selected controller and the available request methods, filters, and possible fields in a JSON post body.

Metadata samples for controllers and get information

Request

{{api_root}}/{{customer_id}}/leaveIntegrations/metadata

Response

{
"entityInformation": ["Table: LeaveIntegration"],
"filterUpdateDelete": ["LeaveId", "EmployeeId", "StartDate", "EndDate", "PayrollUpdateStatus", "RowNumber"],
"body": [
"columns",
"integrationSystemName",
"searchCondition",
"top",
{
"customSearchCondition": ["FromDate"]
}
]
}

In the above code snippet:

  • The entityInformation section explains which tables and views from MindKey are used for this controller.
  • The filterUpdateDelete section describes the fields that can be used for filtering when updating or deleting records in MindKey.
  • The body section always has the subsections columns, top, SearchCondition and integrationSystemName.
    • In the columns subsection, you can specify either all columns from controller using "*" or specific columns.
    • In the top subsection, a number can be specified to only return this exact number of records.
    • In the searchCondition subsection, you can specify different selection criteria. By default, criteria are AND.
    • In the integrationSystemName subsection, you can establish the names that are created in the integrationsystem setup in MindKey. The export value is returned if values for the given integrationsystem are set up in the integration exportkeys.
  • In the CustomSearchCondition section, FromDate can be given and then only records created or modified after this date are returned.

IntegrationSystemName

If integrationsystem "Visma" is created in Integrationsystems and a value for integrationssystem "Visma" and Table LeaveCode is created, a column with name LeaveCodeName_ExportKey is returned for all controllers where field LeaveCodeName exists. If no value is setup for the actual leave code in the integration exportkeys, the column returns null.

Below you can find a PowerShell LeaveIntegration export example:

$body = @{
columns = "*"
integrationSystemName = "MyLeaveSystem"
searchCondition = @(
@{
column = "PayrollUpdateStatus"
value = "2" # 1 = ReadyForPayroll, 2 = MovedToPayroll, 3 = PayrollUpdated
}
)
}

This example returns the following columns:

{
"LeaveId": "1110",
"Version": 1,
"LeaveCodeName": "Vacation",
"StartDate": "2019-09-10T00:00:00",
"EndDate": "2019-09-13T00:00:00",
"BalanceEffect": "-4.0",
"BalanceUnit": 1,
"EmployeeId": "1086",
"Origin": 0,
"PayrollUpdateStatus": 3,
"PayrollDateTime": "2020-04-01T11:14:04",
"Correction": false,
"RowNumber": 1530,
"CreatedBy": "mindkey@mindkey.com",
"CreatedDateTime": "2019-11-21T16:19:53",
"ModifiedBy": "MindKey Service",
"ModifiedDateTime": "2020-04-01T11:14:04",
"VersionStamp": 4,
"DocumentsExists": false,
"ExternalStatus": 0,
"EmployeeId_ExportKey": null
}

Last column EmployeeId_ExportKey is returned because EmployeeId column is selected and a LeaveCode has been setup for integrationsystem equal to MySalarySystem. Since no setup value or EmployeeId equal to "MFU" exists, null is returned.

If you setup LeaveCode for integrationsystem to be equal to MySalarySystem, the LeaveCodeName_ExportKey column is returned.

HTTP headers for MindKey REST requests

In the quick start guide above, we used the MindKeyRest Powershell module, which also handled the needed request headers. If you do not use that, you need to specify them by yourself.

The table below presents the standard request headers that MindKey accepts, as well as the custom MindKey headers that you can use.

HTTP HeaderRequiredDescription
Accept (standard)OptionalAccept indicates the formats the client accepts for the response. This header pairs with the Content-Type header, which specifies the format required by MindKey for the request. Currently, all MindKey REST interfaces require request bodies to be formatted in JSON, and JSON is the default and only format returned in response bodies. For more information, see Microsoft Time Zone Index Values.

Example: Accept: application/json
Content-Type (standard)Conditionally required

  • POST operations
  • PUT operations
Content-Type indicates the format of the request body provided by the client. This header is required for all POST and PUT operations; application/json is currently the only supported value.

Example: Content-Type: application/json
TimeZone (MK custom)Conditionally required

  • POST operations containing datetime
TimeZone must be specified in request header if the body for a post operations containing a DateTime value that is passed as UTC.

Example: TimeZone: Romance Standard Time.

For a full list of accepted values, see Microsoft Time Zone Index Values.
SystemUser (MK custom)OptionalSystemUser specifies a username, that is used when logging who modified data in MindKey. It defaults to ‘MindKey Service’ if not set.
ApplicationName (MK custom)Optional
Culture (MK custom)Optional
Language (MK custom)OptionalLanguage defines in which language the user wants to receive the response. Default to en-US, if not set, or set to unsupported language.

Errors

The MindKey integration API uses standard HTTP status codes. 2xx codes indicate success, 4xx codes indicate an error in the information provided, and a code in the 5xx range indicates an error on MindKey's servers. The table below describes the common status codes.

Error codeDescription
200The request worked as expected.
404The resource could not be found.
405Method not allowed. Encountered when using a HTTP method that is not allowed on this endpoint.
500Something went wrong in the MindKey API.