Payroll schedules

Read and change your contractor and employee payroll cadence in the Wingspan V3 API, and preview upcoming pay periods.

This page explains your payroll schedule: the cadence Wingspan uses for scheduled payroll, how to read and change it, and how to preview upcoming pay periods before you commit to a change.

Two schedules per Account

Your Account has at most two payroll schedules, one for each worker type:

typeDrives
ContractorScheduled contractor and vendor payroll dates.
EmployeeEmployee pay periods and on-cycle Employee payroll runs.

You don't create or delete a schedule. Each one exists for your Account and is addressed by its type: /v3/payments/payroll-schedules/Contractor or /v3/payments/payroll-schedules/Employee. Earlier versions of the API called the Contractor type ContractorVendor, so update any stored paths or comparisons. An Account that has never set a cadence still gets its schedules back from the list, with frequency and interval missing. That's how you detect "not set up yet".

A schedule holds timing only. Whether payroll runs at all, and which account funds it, live on your payer settings. If you want to stop scheduled contractor payroll, set payrollSettings.status to Cancelled there; the cadence is kept, so setting it back to Active resumes it.

Payroll runs you create through the API are off-cycle and don't depend on the schedule. See Payroll runs.

Terms

TermMeaning
Due dateThe date on the payable or invoice.
Pay dateThe scheduled date a run pays. On a payroll run, payDate.
CutoffFor contractor schedules, the date the scheduled run takes payables up to. Each entry in scheduleDates[] carries a server-computed cutOffDate.
Processing lead timeprocessDaysBeforeDue: the gap between a contractor occurrence's cutoff and its pay date, when your Account has it enabled.
Pay periodFor employee payroll, the work window a run pays. See Pay periods.

Read your schedules

Call GET /v3/payments/payroll-schedules for both, or GET /v3/payments/payroll-schedules/{type} for one. Filter the list with filter[type][eq].

curl "https://api.wingspan.app/v3/payments/payroll-schedules/Contractor" \
  -H "Authorization: Bearer $WINGSPAN_TOKEN"
// (trimmed)
{
  "id": "Py6Kt1Wz8Qm4Rx2Lv9Nb5S",
  "accountId": "Aq9Zt4Mx1Kc7Rv3Ln8Pw2B",
  "type": "Contractor",
  "frequency": "Weekly",
  "interval": 1,
  "dayOfWeek": "Friday",
  "startDate": "2026-09-04",
  "scheduleDates": [
    { "date": "2026-09-25", "cutOffDate": "2026-09-23", "status": "Completed" },
    { "date": "2026-10-02", "cutOffDate": "2026-09-30", "status": "Pending" }
  ]
}

Both schedules share the same id; type tells them apart.

Schedule fields

FieldApplies toWhat it does
frequencyBothDaily, Weekly, SemiMonthly, Monthly, or Annual.
intervalBoth"Every N periods". Biweekly is Weekly with interval: 2; there's no separate biweekly value.
startDateBothWhen the cadence starts.
endDateContractorWhen the cadence ends.
dayOfWeekContractorThe weekday for a Weekly schedule.
dayOfMonthContractorThe day for a Monthly schedule.
processDaysBeforeDueContractorProcessing lead time, when enabled for your Account.
scheduleDates[]ContractorUpcoming and past occurrences: date, cutOffDate, and status (Pending, Completed, Skipped, or Modified). Empty for Employee schedules.

Employee schedules accept only Weekly with interval 1 or 2, or Monthly with interval 1.

Change a schedule

Call PATCH /v3/payments/payroll-schedules/{type}. Send only what you're changing.

curl -X PATCH "https://api.wingspan.app/v3/payments/payroll-schedules/Contractor" \
  -H "Authorization: Bearer $WINGSPAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "frequency": "Weekly", "interval": 2, "dayOfWeek": "Friday", "startDate": "2026-10-09" }'

Rules to know:

  • interval needs frequency in the same request.
  • Clearing a field that's already set isn't supported here.
  • A field the schedule type can't store returns 422 naming the field and type. It's never silently ignored. For example, dayOfWeek on the Employee schedule is rejected.
  • Changing the cadence re-derives the contractor scheduleDates.
  • The Employee schedule can only be changed while it's fresh: one pay period exists and its on-cycle run is still Draft. After that, a change returns 409.

Move or skip one contractor occurrence

To change a single upcoming date without changing the cadence, send the full scheduleDates series back with your edit, and no cadence fields in the same request. Entries are matched by position, so a short or reordered array edits the wrong runs.

  1. Read the schedule.
  2. Find the entry by its date in that fresh read.
  3. Change its date, or set its status to Skipped.
  4. Send every entry, in the same order.

Completed belongs to payroll execution. You can only send it on an entry that echoes an unchanged completed run.

Preview pay periods

Before changing a cadence, preview what it produces. POST /v3/payments/payroll-schedules/{type}/preview-pay-periods projects periods across a window using the same date math Wingspan uses to generate them. Nothing is saved.

curl -X POST "https://api.wingspan.app/v3/payments/payroll-schedules/Contractor/preview-pay-periods" \
  -H "Authorization: Bearer $WINGSPAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "fromDate": "2026-10-01", "toDate": "2026-12-31", "count": 12 }'
// (trimmed)
{
  "periods": [
    { "sequence": 1, "startDate": "2026-09-25", "endDate": "2026-10-01" },
    { "sequence": 2, "startDate": "2026-10-02", "endDate": "2026-10-08" }
  ]
}

A period is returned if it overlaps the window. count defaults to 12 and can be up to 120. For a contractor schedule, a period runs from one payroll date to the day before the next. For an employee schedule, it's the work window, and its pay date falls after endDate.

Employee pay periods

Employee pay periods are created by your Employee schedule, never through the API. Read them with GET /v3/payments/pay-periods, filtered by filter[startDate][gte], filter[startDate][lte], filter[endDate][gte], filter[endDate][lte], or filter[externalId][eq]. Each has a payPeriodNumber and payPeriodsPerYear. You can set only externalId and metadata on a pay period, with PATCH /v3/payments/pay-periods/{payPeriodId}.

Common mistakes

  • Expecting a Biweekly frequency. Use Weekly with interval: 2.
  • Sending a partial scheduleDates array. Always send the complete series in order.
  • Changing the schedule to stop payroll. Stop it on payer settings with payrollSettings.status: Cancelled instead.
  • Assuming the schedule filters an API-created run. A Contractor run created with ApprovedPayables pays every approved payable regardless of the schedule or due date.

Related pages


Did this page help you?