Get Results
With a successful status confirmation, retrieve the generated predictions by invoking the GET /results
endpoint with the Job ID. This is not necessary if you have used the real-time endpoint.
The result response
Prediction response format
message | string or null Info from the job |
page | integer >= 1 Default: 1 The current page of the job |
pages | integer >= 1 Default: 1 The number of pages for the job |
required | Array of objects (Dataset Result) The array of results for each dataset. |
{- "message": "string",
- "page": 1,
- "pages": 1,
- "datasetResults": [
- {
- "id": "392fb924-0744-4fff-bff7-9ae89ce8fe9d",
- "severityThresholds": {
- "lowMid": 10,
- "midHigh": 25
}, - "findings": [
- {
- "type": "INCREASE",
- "fields": [
- {
- "key": "subType",
- "value": "Net"
}
], - "affectedEmployeeIds": [
- "7b3a3735-b23b-4b42-a46d-ad93e947c93e",
- "619a835a-ab4c-4022-8c33-3e056a35de65"
]
}
], - "payslipResults": [
- {
- "id": "aa3e4707-80b5-4a73-b551-54fc6629d4e6",
- "score": 49,
- "findings": {
- "observed": [
- {
- "predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
- "transactionId": "ca9185a0-1928-4b1d-8257-8f07e0d83485",
- "score": 42,
- "context": [
- {
- "employeeId": "181bfaaf-cc0a-409e-b811-1bc2739f6879",
- "employeeGroups": "Engineering"
}
], - "field": "amount",
- "anomalyType": "HIGH_VALUE"
}
], - "missing": [
- {
- "predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
- "score": 42,
- "context": [
- {
- "employeeId": "181bfaaf-cc0a-409e-b811-1bc2739f6879",
- "employeeGroups": "Engineering"
}
], - "expectedField": {
- "key": "subType",
- "value": "Net"
}
}
]
}
}
]
}
]
}
The prediction response consists of multiple objects, one of them being payslipResults. This object contains the explanation and anomalies for each individual payroll transaction.
Each payslipResults[...] object contains multiple score fields, representing the anomaly scores calculated for each feature relevant to the payslip. The id located at the higher level of the JSON object represents the id of the payslip sent for prediction. The score at this level is the anomaly score calculated for the specific payslip.
In the findings list, we have more granular information about which transactions or features related to each payslip contribute to the anomaly score of the payslip itself. The score here relates to individual transactions or features for each payslip.
Each payslipResults[...] contains the anomaly score, the type of anomaly and the context in which the anomaly exists. The object is split into two groups, missing and observed anomalies.
Observed
Observed response format
predictionId required | string A unique identifier for the specific finding, which can be used to reference the finding when submitting feedback. |
transactionId required | string The unique ID of the transaction from the request. |
score required | integer [ 1 .. 100 ] The score of the finding. The higher the score, the more likely it is an anomaly. The score will be between 1 and 100. 100 - is the highes score and 1 is the lowest. Findings with a score of 0 will not be returned. |
Array of objects (Anomaly Context (observed)) Specifiers (key-value pairs) of the context in which the anomaly was found. | |
field required | string The field that the anomaly score is for. |
anomalyType required | string Enum: "GENERAL_ANOMALY" "LOW_VALUE" "HIGH_VALUE" "NEW_VALUE" Description of the type of anomaly (e.g., general, low value, new value). |
[- {
- "predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
- "transactionId": "ca9185a0-1928-4b1d-8257-8f07e0d83485",
- "score": 42,
- "context": [
- {
- "employeeId": "181bfaaf-cc0a-409e-b811-1bc2739f6879",
- "employeeGroups": "Engineering"
}
], - "field": "amount",
- "anomalyType": "HIGH_VALUE"
}
]
Observed anomalies directly correspond to a transaction that was sent for prediction. This means the anomaly specifically references a transaction submitted to the API. As a result, observed anomalies will always include a transactionId in their response, identifying the exact transaction flagged during the prediction.
Additionally, the response includes a field that can be paired with the transactionId to indicate which aspect of the transaction triggered the anomaly score. For example, if the field is "amount," it signals that the amount in this particular transaction was anomalous.
Anomaly Type
The anomaly type describes the category of the anomaly that was returned. This field has enum values, which can be one of the following:
- LOW_VALUE
- HIGH_VALUE
- NEW_VALUE
- GENERAL_ANOMALY
Anomalies where the transaction field's value is unusually low compared to historical data.
Anomalies where the field's value is significantly higher than expected.
Values that are entirely new or very rarely used. This could be on an employee, group (employeeGroups) or dataset level. This means that the value inferred by the field and transactionId is a new value, not previously seen for an employee, an employeeGroup, or on a dataset level.
This value covers anomalies that are detected but don't specifically fall into the low or high value categories. This is because we estimate the anomaly to be a high or low value with a degree of certainty. If an anomaly is returned as a general anomaly, then we are not able to with a high enough degree of certainty estimate this to be a low or high value.
Missing
Missing anomalies occur when data expected in the prediction is absent, rather than linked to a specific transaction. These anomalies indicate missing data that should have been present based on historical patterns.
For example, if an employee has consistently had a transaction with the subType driving_benefit in historical payslips, but the prediction data lacks this subType, the payslip would be flagged as a missing anomaly. This is because the driving_benefit subType is typically present but was omitted in this case.
In these anomalies, a transactionId is not returned, as there is no related transaction. Instead, an expectedField object is provided, which describes the missing data. In the example, the expectedField would have the key subType and the value driving_benefit.
{
"expectedField":
{
"key": "subType",
"value": "driving_benefit"
}
}
Missing response format
predictionId required | string A unique identifier for the specific finding, which can be used to reference the finding when submitting feedback. |
score required | integer [ 1 .. 100 ] The score of the finding. The higher the score, the more likely it is an anomaly. The score will be between 1 and 100. 100 - is the highes score and 1 is the lowest. Findings with a score of 0 will not be returned. |
Array of objects (Anomaly Context (observed)) Specifiers (key-value pairs) of the context in which the anomaly was found. | |
required | object (Finding Field and Value) |
[- {
- "predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
- "score": 42,
- "context": [
- {
- "employeeId": "181bfaaf-cc0a-409e-b811-1bc2739f6879",
- "employeeGroups": "Engineering"
}
], - "expectedField": {
- "key": "subType",
- "value": "Net"
}
}
]
Anomaly scores
Anomaly scoring is a critical aspect of this schema, as indicated by the score field, which quantifies how unusual a field is. The anomaly score is a number between 0-100, where 0 indicates no anomaly and 100 a severe anomaly.
Anomaly scores are relative to the specific characteristics of the dataset — that is, datasets exhibiting substantial variability inherently display higher median anomaly scores compared to more uniform datasets.
Context
A contextual anomaly occurs when a data point is considered anomalous only within a specific context. While the data may appear normal in general, it deviates from expected patterns when evaluated within its particular circumstances. For example, a specific transaction amount might be typical for one employee group but highly unusual for another, depending on factors like role, department, or time period.
The context object is present in both missing and observed anomalies. This is a list of objects, with key-value pairs of the context in which the anomaly was found. The API can return four different types of context objects, with examples of each provided below.
Click to see the full list of possible context values
Here the anomaly is detected with the context of an employee with id "employee-1". This could be that we have an amount that was considerably higher than expected, for that specific employee.
{
"context": [
{
"employeeId": "employee-1"
}
]
}
In this example, the context includes details about both the month and the employee's group. This could mean that the anomaly is related to a missing subType for a specific employeeGroup for a specific month. An example could be that the group normally has a vacation_payment transaction present during that month.
{
"context": [
{
"month": "June",
"employeeGroups": "sales"
}
]
}
Here, the anomaly is detected with the context of the "sales" employee group, but without any specific employee or time period.
{
"context": [
{
"employeeGroups": "sales"
}
]
}
In this example, the context is global, meaning that the anomaly is relevant across the entire dataset, not limited to a specific employee or group.
{
"context": [
{
"global": "global"
}
]
}
In the provided example, the cause of the anomaly score for this payslip is related to a high amount for the transaction with the ID ca9185a0-1928-4b1d-8257-8f07e0d83485. This transaction was flagged with a high anomaly score of 49 under the observed anomalies category, indicating that the amount for this transaction was significantly higher than expected for an employee in the sales group.
Another anomaly is listed under the missing anomalies category, with an anomaly score of 42. This anomaly does not reference a specific transaction with a transactionId but rather points to an expected field (subType: Net) that was missing from the payslip data for employee-1. This suggests that a subType value of "Net" was expected but not found, causing the anomaly, though it is less severe with a lower score.
{
"payslipResults": [
{
"id": "aa3e4707-80b5-4a73-b551-54fc6629d4e6",
"score": 49,
"findings": {
"observed": [
{
"score": 49,
"predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
"context": [
{
"employeeId": "employee-1",
"employeeGroups": "sales"
}
],
"field": "amount",
"transactionId": "ca9185a0-1928-4b1d-8257-8f07e0d83485",
"anomalyType": "HIGH_VALUE"
}
],
"missing": [
{
"score": 42,
"predictionId": "a48e916a-8f6c-4ffd-9494-39425735c30a",
"context": [
{
"employeeId": "employee-1"
}
],
"expectedField": {
"key": "subType",
"value": "Net"
}
}
]
}
}
]
}
Dataset findings
PayrollDetect also returns payroll patterns that are relevant even if they are not anomalous. These findings explain changes detected in the amount for a certain group of employees and provide insights that can be presented to users. For instance, these insights could relate to a large increase in wages for all or a sub-group of the employees with payslips sent for prediction.
A relevant use case for this is during certain months in certain countries when vacation payments are paid out to employees. During these times, a large portion of the employees will experience an increase in their wages. This will not be flagged as anomalous but will be included as part of the findings object.
In the provided example, 6 employees experience an increase in the subType Net. For this to go into effect, a significant number of the employees has to experience these changes. Hence the ... to employee_n in the example.
{
"findings": [
{
"type": "INCREASE",
"fields": [
{
"key": "subType",
"value": "Net"
}
],
"affectedEmployeeIds": [
"employee_1",
"employee_2",
"employee_3",
...
"employee_n"
]
}
]
}