A payroll run is one payroll for a company: the pay for one pay period, or an extra payroll on a date you choose. The Payroll Run API is how you run payroll in Payroll Infrastructure. You add each worker's pay to a run as items, have Everee calculate it, fix anything that blocks it, and approve it. Everee then funds the run from the company's funding account and pays the workers.
For the end-to-end walkthrough, see Running payroll. This guide is the reference for the run itself.
Payroll Infrastructure onlyPayroll runs exist only for Payroll Infrastructure companies. Every endpoint that changes a run returns
400for a company whose payroll is run in the Everee admin portal. For a Payroll Infrastructure company, payroll runs are the only way to pay workers: the Payables and Timesheets endpoints that create pay return400, and payments can't be approved outside a run.
Call these endpoints with the company's API key. See Authentication and API tokens.
| Endpoint | What it does |
|---|---|
| List payroll runs | Lists the company's runs, newest first |
| Retrieve a payroll run | Retrieves one run |
| Create an off-cycle payroll run | Creates an extra run for a pay date you choose |
| Open a payroll run | Sets the pay date of an UNOPENED run, so it can take items |
| Change a payroll run's pay date | Moves the pay date of a run that isn't approved |
| List a payroll run's items | Lists the pay you've added |
| Add items to a payroll run | Adds or updates pay, by your externalId |
| Remove an item from a payroll run | Removes one item |
| List a payroll run's payments | Each worker's payment: wages, taxes, deductions, employer costs, net pay and payouts |
| Exclude a payment from a payroll run | Leaves a worker out of the run |
| Calculate a payroll run | Has Everee calculate the run's payments |
| List a payroll run's blockers | What's keeping the run from being approved |
| Approve a payroll run | Approves the run for payment |
| Reopen a payroll run | Takes back an approval, before the reopen deadline |
| Retrieve a payroll run's funding | How the run is funded, and whether that needs your action |
| Retry a payroll run's funding | Retries a funding you've fixed |
Two related APIs complete the picture. The Net Payouts API lists what each worker was paid and how. The Requirements API lists what's keeping the company's payroll from processing, across every run.
Listing and paging
Every list in this API, and in the Net Payouts and Requirements APIs, uses cursor pagination. Send limit for the page size, from 1 to 1,000 (100 if you leave it out). Each page has hasNextPage, and when there's a next page, nextCursor: send it as after to get that page. Keep going until hasNextPage is false.
Each list has a fixed order, so page, size and sort aren't accepted:
| List | Order |
|---|---|
| Payroll runs | Newest first: by periodStart, then id |
| A run's items | The order they were added |
| A run's payments | By id |
| A run's blockers | By source domain, then type, then subject (IDs in byte order, so uppercase before lowercase) |
| Net payouts, requirements | Newest first |
Items added while you page through a run land after the ones you've read, so a pass through the list never skips or repeats an item. Pages don't carry totals: the run itself has itemCount, paymentCount and totalNetPay.
Regular and off-cycle runs
Regular runs come from the company's payroll calendar. When the calendar creates a pay period, Everee creates its run with status UNOPENED and sends payroll-run.created. Open it with a targetPayDate to start adding pay.
Off-cycle runs are extra payrolls, such as a bonus run or a final paycheck. Create one with a targetPayDate. It starts OPEN, on a pay period of its own, and Everee sends payroll-run.created.
Pay dates and deadlines
targetPayDate must be a banking day, and no earlier than the first date the company can pay. That date depends on the company's funding type, which for an off-cycle run is its funding type for ad hoc payments. A pay date that's too early returns 400 naming the earliest date allowed.
Each run has up to three deadlines. Read them from the run rather than working them out yourself:
| Field | Meaning |
|---|---|
approvalDeadline | Approve by this time for workers to be paid on targetPayDate. Set when the run is opened or created, and recalculated when you change the pay date. |
reopenDeadline | Set when the run is approved. Until this time you can reopen it. It's the start of the next window in which Everee sends payments, and at least 15 minutes after approval. |
processingBlockedDeadline | Set when the run is PROCESSING_BLOCKED: fix its funding and retry by this time. |
All timestamps are UTC.
A run also has its totals: itemCount, paymentCount (leaving out excluded payments), and totalNetPay, those payments' net pay as last calculated. totalNetPay is only final once the run is READY.
Payroll run statuses
| Status | What it means | What you can do |
|---|---|---|
UNOPENED | A regular run waiting for its pay date | Open it |
OPEN | Taking items | Add, update and remove items, exclude payments, change the pay date, calculate |
CALCULATING | Everee is calculating its payments | Add items and exclude payments: the calculation picks them up. Calculating again is allowed and safe |
BLOCKED | Calculated, but something must be fixed first | Read its blockers, fix them, and calculate again. Items, exclusions and the pay date can still change |
READY | Calculated, and nothing blocks it | Approve it. Any change to its items or payments sends it back to OPEN |
APPROVING | Your approval is being processed | Wait. Approving again is allowed and safe |
APPROVED | Approved, waiting for money to move | Reopen it before reopenDeadline |
PROCESSING | Everee is moving the run's money | Wait |
PROCESSING_BLOCKED | The run's funding needs your action | Read its funding, fix it, and retry before processingBlockedDeadline |
PARTIALLY_PAID | Processing finished, but not every payout reached the worker | Check its net payouts |
PAID | Every payout has gone out | Nothing: the run is complete |
A run moves forward like this:
UNOPENED→OPENwhen you open it. An off-cycle run starts atOPEN.OPEN→CALCULATINGwhen you calculate it.CALCULATING→READYwhen nothing blocks it,BLOCKEDwhen something does, or back toOPENwhen items were added during the calculation and still need calculating.READY→APPROVING→APPROVEDwhen you approve it.APPROVED→PROCESSINGwhen money starts moving, thenPAIDorPARTIALLY_PAID. A direct deposit counts as delivered two banking days after it's sent, if it hasn't come back, so a run can stayPROCESSINGafter every payout showsPAID.
And back:
READYorBLOCKED→OPENwhen you add, update or remove an item, or exclude a payment.BLOCKED→OPENwhen its last blocker is resolved. Calculate it again.APPROVED→OPENwhen you reopen it. Its payments are unapproved.APPROVED→OPENwhen Everee can't approve its payments on their funding date. Calculate and approve it again.PROCESSING_BLOCKED→PROCESSINGwhen you retry its funding, orOPENwhenprocessingBlockedDeadlinepasses. Approve it again for a later pay date.PROCESSING→OPENwhen the company's bank returns the run's funding debit before workers were paid. The run gets aFUNDING_FAILEDblocker. Make sure the account has the money, then calculate and approve it again.
Every change sends a payroll-run.status-changed webhook event with the run and its previous status. A request that a run's status doesn't allow returns 409, with the status in errorMessage.
Adding, updating and correcting items
An item is one amount of pay for one worker: hours at a rate, a bonus, a reimbursement. You calculate the amount and send it under a pay code. See Pay codes and gross pay basics. Send each item with your externalId, the worker, a label, a payCode and an amount, and unitCount and unitRate when the pay is per unit, such as hours. Everee sets the rest:
| Field | Set by Everee to |
|---|---|
type | PAYROLL_RUN_ITEM, which marks the item as added to a payroll run |
payableModel | PRE_CALCULATED: the amount you sent is what's paid |
earningTimestamp | The run's earning date |
They're returned on each item, and ignored if you send them.
Each item has your externalId. What happens depends on whether Everee has seen it before:
The externalId is | What happens |
|---|---|
| New | The item is added to the worker's payment in the run. The payment is created if the worker doesn't have one yet. |
| Already an item of this run | The item is updated, and the difference added to the worker's payment. |
| On a payment you excluded | The item moves to this run. |
| On a payment that's been paid | Rejected with PAYABLE_ALREADY_PAID, unless you send correction-authorized=true. Then the paid item is kept as it was, and this one corrects it. |
| On another payment that hasn't been paid | Rejected with PAYABLE_ON_ANOTHER_PAYMENT. Remove it from that payment first. |
The response is the items you sent, as the run now has them. A worker's payment in the run combines all of that worker's items, so one worker never has two payments in one run.
Earning date
Every item in a run is earned on the last day of the run's pay period, its periodEnd. For a worker whose employment ended before periodEnd, it's their end date instead, so their final pay can still be added. earningTimestamp is the start of that day in the worker's time zone.
An item that moves to another run, or corrects a paid item in a later run, takes the earning date of the run it's added to.
Sending many items
A request can add up to 1,000 items. To add more, send several requests: a run with a few thousand items takes a few calls.
Everee checks every item before saving any. If any item can't be accepted, nothing is saved, and the 400 response lists every failing item, with its position, the IDs you sent, an errorCode, and the field at fault. See Errors in bulk requests. Fix them and send the whole request again: items are matched by externalId, so sending the same items twice is safe.
errorCode | Meaning |
|---|---|
WORKER_NOT_FOUND | No worker matches the item's workerId or externalWorkerId |
PAYABLE_EXTERNAL_ID_NOT_UNIQUE | The request sends the same externalId more than once |
PAYABLE_ALREADY_PAID | The item has been paid. Send correction-authorized=true to correct it |
PAYABLE_ON_ANOTHER_PAYMENT | The item is on another payment that hasn't been paid. Remove it there first |
PAYROLL_RUN_PAYMENT_CLOSED | The worker's payment in this run was excluded, or is past calculation, so it can't take new items |
INVALID_REQUEST | Anything else, such as a missing or negative amount, an unknown pay code, or a cost center type that doesn't exist or is archived. errorMessage says what to change |
When an item updates one the run already has, it's checked as the update leaves it: a field you leave out, such as a leave payout's unitCount, keeps its value.
Remove an item takes its amount off the worker's payment, and deletes the payment when it was the last item. Exclude a payment leaves a worker out of the run entirely: the payment stays listed with status EXCLUDED and the reason you gave, and its items are deleted. A payment can be excluded until it's approved.
Items carry their worker as workerId and externalWorkerId. externalWorkerId is null for a worker you created without one. Filter items and payments by either, with worker-id and external-worker-id.
earningTimestamp is Unix epoch seconds, and workLocationId is a number, as in the payables API. Every other ID in this API is a string, and every other time is an ISO 8601 timestamp.
Calculating
Calculate a payroll run queues the run, which moves to CALCULATING. Calculation happens in the background: wait for the payroll-run.status-changed event rather than polling, and read the run when it arrives.
While Everee calculates, it also checks the run for anything that would stop it being paid. For a company that funds payroll before it's paid out, that includes the company's funding account balance: a run the balance can't cover is BLOCKED with INSUFFICIENT_FUNDS, and the balance is checked again on each calculation.
Blockers
List a payroll run's blockers to see why a run is BLOCKED. Each blocker says what it's about (subjectType and subjectId), its type, and resolutionInstructions for fixing it. Blockers are returned in a fixed order, by source domain, then type, then subject, and can't be sorted.
Most blockers come from a requirement, and share its fields. A blocker that comes from a payment's own error, or from the company not being approved yet, has no requirementId. The requirement types say what each one means.
When a run's last blocker is resolved, the run goes back to OPEN. Calculate it again to get to READY.
Payments
List a payroll run's payments once the run is calculated. Each payment is one worker's pay, with everything it was calculated to:
taxableWagesandnonTaxablePay, by pay code, and their totalsemployerTaxesandemployeeTaxWithholdings, with the wages each was calculated onemployeeDeductions, including garnishmentsemployerAdditionalCosts: employer contributions, and workers' comp premiums with their class and ratetotalNetPay, and thenetPayoutsit's paid out as
Payment statuses
| Status | Meaning |
|---|---|
READY_TO_CALCULATE | Has items that haven't been calculated |
PROCESSING | Being calculated |
PENDING_APPROVAL | Calculated, waiting for the run to be approved |
ERROR | Can't be paid as it is. errorType says why |
UNPAYABLE_WORKER | Can't be paid until the worker's profile is fixed. errorType says what's missing |
PENDING_VERIFICATION | Waiting for its hours to be verified |
PENDING_PAYMENT | Approved, or approved and scheduled for its funding date |
PENDING_FUNDING | Waiting for the company's funding to clear |
PAID | Sent to the worker |
EXCLUDED | Left out of the run |
AUTO_APPROVED | Approved automatically |
Approving and reopening
Approve a READY run before its approvalDeadline. The run moves to APPROVING, then APPROVED. If its payments are funded on a later day, Everee approves them on that day.
Approval is refused with 409 while a funding debit returned after workers were paid hasn't been repaid. The company then has an open FUNDING_FAILED requirement. Contact Everee Customer Success to repay it.
Until reopenDeadline, you can reopen an APPROVED run. Its payments are unapproved and it goes back to OPEN, so you can change it and approve it again.
Funding
Once a run is approved, retrieve its funding to follow the money from the company's funding account. Before approval it returns 404.
| Status | Meaning |
|---|---|
PENDING | Not sent yet. The amount and date are what Everee expects to debit |
UNDER_REVIEW | Everee is reviewing it before sending it |
NEEDS_ACTION | You need to act. resolutionInstructions says what to do |
FUNDED | The money was collected |
FAILED | The debit failed or was returned |
A funding that needs action puts the run in PROCESSING_BLOCKED. Follow resolutionInstructions: for example, move money into the account, or send the wire. Then retry the funding before the run's processingBlockedDeadline. The run goes back to PROCESSING: a funding held for insufficient funds is sent when the balance covers it, and otherwise goes back to review. If the deadline passes first, the run goes back to OPEN, to approve again for a later pay date.
A retry's funding names the funding it replaced in previousFundingId. Everee sends payroll-run.funded when a funding is collected and payroll-run.funding-failed when one fails, each with the funding.
Webhook events
| Event | Sent when | data.object |
|---|---|---|
payroll-run.created | A run is created, regular or off-cycle | The payroll run |
payroll-run.status-changed | A run's status changes | The payroll run, plus previousStatus |
payroll-run.funded | A run's funding is collected | The funding |
payroll-run.funding-failed | A run's funding fails | The funding |
Each event's object is the same as the API returns. See Payroll Run Events for the payloads, and the net payout and requirement events.
Errors
| Status | When |
|---|---|
400 | The ID isn't numeric; a filter, limit or after is invalid; page, size or sort was sent; targetPayDate isn't allowed; items can't be accepted (every failing item is listed); a request has more than 1,000 items; or the company isn't a Payroll Infrastructure company |
404 | The run, item or payment doesn't exist for the company, or the run has no funding yet |
409 | The run's status doesn't allow the request, or a deadline has passed |
422 | The body is missing a required field, or a field is invalid |
The error body is described in Requests and responses.