Errors during payroll preview

In API version 2025-01-01, users have the option to preview payrolls synchronously or asynchronously. For more information about payroll preview, refer to Payroll Preview and Approval.

When previewing payrolls synchronously, all errors are returned in the same fashion. The preview request will return a 400 response, with an error message that looks like the following:

{
    "error": {
        "type": "payroll_already_approved",
        "message": "Payroll is already approved, and further changes are not allowed"
    }
}

The above is how errors are returned in preview for all previous API versions (e.g., 2023-04-04) as well.

When previewing payrolls asynchronously, errors may be returned in two different ways. Some errors will return in the same fashion as the synchronous preview errors above. However, other errors are not caught and returned until after the preview calculation is completed; these are errors that depend on the results of the preview calculation in order to be identified.

For this second category of errors, the asynchronous preview request will return an initial 200 response (with "preview.status": "calculating", indicating that the preview is able to be successfully initiated), but on fetching the payroll after the preview is completed, the preview object on the payroll will display an error message. Here is an example:

{
  ...,
  "preview": {
    "messages": [
      {
        "severity": "aborted",
        "code": "3dp_cash_requirement_limit_exceeded",
        "message": "Payroll exceeds three-day payroll cash requirement limit of $1,000,000. To proceed, please change the payroll's funding_payment_method to 'wire'."
      }
    ],
    "status": "failed",
    "started_at": "2025-03-21T21:42:21.672559Z"
  }
}

preview error messages for asynchronous preview also contain a new field called severity. This field is intended to distinguish between errors which caused the payroll to be aborted (which indicates that the preview calculation was invalid, and is not saved on the payroll), and blocking (which indicates that the preview calculation was saved, but the payroll preview will not able to be approved unless the message is addressed).

Below are the list of errors that may be returned on payroll preview, whether they are surfaced in a 400 response or a preview error message during asynchronous preview, and if applicable, their severity:

TypeMessageAsynchronous Response TypeSeverity
payroll_already_approvedPayroll is already approved, and further changes are not allowed400 Responsen/a
non_empty_payroll_requiredPayrolls must have at least one item or contractor payment to be previewed or approved400 Responsen/a
net_pay_negativeOne or more negative net pay errors occurred during handling of payroll {payroll.public_id}:

Followed by a list of the following:

Only imputed wage entered; Regular or supplement earnings required to cover taxes on imputed wage.

Full pre-tax retirement benefit 401k amount cannot be withheld.
preview Error Messageaborted
3dp_cash_requirement_limit_exceededPayroll exceeds three-day payroll cash requirement limit of $1,000,000. To proceed, please change the payroll's funding_payment_method to 'wire'.preview Error Messageaborted
credit_limit_exceededThe payroll failed credit limit validation. To proceed, please change the payroll's funding_payment_method to 'wire' or update the payroll's processing_period to either 'three_day' or 'four_day' (note: updating the processing_period may also necessitate a change to the payroll's payday in order to provide adequate time for approval).preview Error Messageaborted

Today, all errors surfaced have a severity of aborted. However, Check may add new error types with a blocking severity, or recategorize the severity of existing errors over time. It is recommended that your integration with error messages in asynchronous preview read the severity field in order to determine whether preview calculation results are available to be displayed.