Off-Cycle
Runs a payroll outside the company's normal pay schedule — for example, a bonus run, a correction, or pay for a single terminated employee. Unlike Run Payroll, which starts a run for the whole company on its existing schedule, this call lets you set custom pay period dates, a pay date, and a specific list of employees.
Requires a bearer access token (see How to Get API Access). CLIENT_ID is the company identifier returned as id when you create the company.
Start an off-cycle payroll run
POST https://api.worklio.com/wep/companies/{CLIENT_ID}/payroll/offcycle
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
startDate | date-time | null | Yes | Pay period start date. |
endDate | date-time | null | Yes | Pay period end date. |
payDate | date-time | null | Yes | Pay date. |
month | int32 | null | No | Month (1–12). |
payrollInMonth | int32 | null | No | Payroll in month. |
includeFlatAmountDeductions | boolean | null | No | Include flat-amount deductions in the run. |
includeArrears | boolean | null | No | Include arrears in the run. |
includeScheduledPay | boolean | null | No | Include scheduled pay in the run. |
includeTimeOffAccruals | boolean | null | No | Include time-off accruals in the run. |
sendPaydayAnnouncementEmail | boolean | null | No | Send the payday announcement email for this run. |
employeeIDs | array of int32 | null | Yes | Employee IDs to include in this run. |
payFrequencyOverride | int32 (enum) | Yes | Pay frequency to use for this run. See values below. |
payFrequencyOverride values
payFrequencyOverride values| Value | Name |
|---|---|
| 0 | NA |
| 1 | Weekly |
| 2 | BiWeekly |
| 3 | SemiMonthly |
| 4 | Monthly |
Example request
require("dotenv").config();
const TOKEN = process.env.API_KEY;
const CLIENT_ID = process.env.CLIENT_ID;
const EMPLOYEE_ID = process.env.EMPLOYEE_ID;
const url = `https://api.worklio.com/wep/companies/${CLIENT_ID}/payroll/offcycle`;
const payload = {
startDate: "2026-09-19",
endDate: "2026-09-25",
payDate: "2026-09-28",
month: null,
payrollInMonth: null,
includeFlatAmountDeductions: true,
includeArrears: false,
includeScheduledPay: true,
includeTimeOffAccruals: false,
sendPaydayAnnouncementEmail: false,
employeeIDs: [EMPLOYEE_ID], //with more employees in can be [EMPLOYEE_ID, EMPLOYEE_ID2,...]
payFrequencyOverride: 0
};
async function runOffCyclePayroll() {
const response = await fetch(url, {
method: "POST",
headers: {
accept: "application/json",
"api-version": "2.0",
authorization: `Bearer ${TOKEN}`,
"content-type": "application/json",
"x-api-version": "2.0"
},
body: JSON.stringify(payload)
});
console.log(response.status);
const raw = await response.text();
console.log(JSON.stringify(JSON.parse(raw), null, 2));
}
runOffCyclePayroll();curl -s -X POST "https://api.worklio.com/wep/companies/$CLIENT_ID/payroll/offcycle" \
-H "accept: application/json" \
-H "api-version: 2.0" \
-H "authorization: Bearer $API_KEY" \
-H "content-type: application/json" \
-H "x-api-version: 2.0" \
-d '{
"startDate": "2026-09-19",
"endDate": "2026-09-25",
"payDate": "2026-09-28",
"month": null,
"payrollInMonth": null,
"includeFlatAmountDeductions": true,
"includeArrears": false,
"includeScheduledPay": true,
"includeTimeOffAccruals": false,
"sendPaydayAnnouncementEmail": false,
"employeeIDs": ['"$EMPLOYEE_ID"'],
"payFrequencyOverride": 0
}' | jq .Example response
{
"companyId": 1028,
"runId": 1002133,
"payrollType": 2,
"startedOn": "2026-09-18",
"payDay": "2026-09-28",
"periodStart": "2026-09-19",
"periodEnd": "2026-09-25",
"daysToProcessPayments": 4,
"deadline": "2026-09-24T21:00:00Z",
"currentUIStep": 0,
"currentProcStep": 501,
"currentProcStepDesc": "Payroll Engine Activated",
"currentProcStepProgress": 0,
"currentProcStepStatus": 1,
"direction": 0,
"isPayrollBlocked": false,
"canUserOverride": false,
"errors": [],
"warnings": []
}payrollType is 2 for a run started through this endpoint, versus 0 for a regular scheduled run started through Run Payroll.
A200response here does not guarantee every ID inemployeeIDswas actually added to the run. An employee is only added if they aren't already part of another payroll that's currently being processed — if they are, the call still returns200and the run is created, but that employee is silently left out. Check the run's employee list before relying on who's included.
Advancing and finalizing the run
Once you have runId, advance and finalize the run the same way as a regular payroll run — see steps 2 and 3 in Run Payroll.
Updated 17 minutes ago
Did this page help you?
