How the Worklio Payroll API Works
Short answer: A payroll API lets your software run payroll for your customers by sending HTTP requests, instead of using a payroll provider's screens. With the Worklio Embedded Payroll (WEP) API, you create a company for each customer, add its employees, and run payroll. Worklio calculates the pay and taxes. This page explains how the pieces fit together. To build it step by step, see How to embed payroll in your product.
For what embedded payroll is and how the three integration paths compare, see What is embedded payroll. The component library still connects its data through this API, so this page applies to that path too.
What a payroll API does
A payroll API turns the work of running payroll into requests your product can make. Your product sends the data: who the employer is, who the employees are, and when to run payroll. The payroll provider's engine does the calculation.
| Your product | Worklio |
|---|---|
| Collects company and employee details from your customer. | Stores them and checks them. |
| Starts, advances and finalizes each payroll run. | Calculates payroll taxes using about 11,000 local payroll rules for taxes, withholdings, deductions and benefits. |
| Shows your customer the result in your own screens. | Supports paying employees by check or direct deposit. |
WEP is a U.S. payroll product.
How the API is organized
The API has four main objects. Each one belongs to the one above it.
| Object | What it is | Identifier in URLs |
|---|---|---|
| Developer account | Your login to Worklio. It owns the companies you create. | None. You sign in with it to get API access. |
| Company | One of your customers. Every company has its own employees, bank accounts and payroll runs. | CLIENT_ID |
| Employee | A person paid by a company. Employees and contractors are both employees in the API. | EMPLOYEE_ID |
| Payroll run | One payroll for one company and one pay period. | runId |
A company's pay schedule comes from its payroll policy: the pay frequency, the end date of the first pay period, and the first pay date. You can send a payroll policy when you create the company or add one later. See Payroll Policies.
Every endpoint for a company sits under the company's path:
https://api.worklio.com/wep/companies/{CLIENT_ID}/...
For example, a company's employees are at .../employees and its payroll runs are at .../payroll.
API versions
Send the version you want in a header on every request. The endpoints under /wep/... use version 2.0. A few older list endpoints under /api/public/... use version 1.0. They support pagination, filtering and sorting, and their responses use PascalCase field names. See Pagination, filtering and sorting. If you name a version an endpoint does not support, the API returns 400 with the code UnsupportedApiVersion.
Authentication
Every request needs a bearer access token. Request one from the token endpoint:
POST https://api.worklio.com/connect/token
A token is valid for 24 hours, so request a new one each day. Send it in the Authorization header as Bearer {token}. If you are building an app where your own users sign in through the browser, Worklio also provides a browser sign-in flow through the @worklio/sdk package. See How to get API access for both flows and code examples.
Making a request
Requests and responses use JSON. Every request to a /wep/... endpoint sends these headers:
accept: application/json
api-version: 2.0
x-api-version: 2.0
authorization: Bearer {ACCESS_TOKEN}
content-type: application/json
Here is a request that lists the companies on your developer account:
curl -s -X GET "https://api.worklio.com/wep/companies" \
-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" | jq .[
{
"id": 1029,
"name": "Joes Fishing Equipment",
"fein": "123456789",
"status": 1,
"uiNumber": 1057,
"createdOn": "2026-09-11T11:51:16Z"
},
{
"id": 1031,
"name": "Sarahs Music",
"fein": "123456789",
"status": 1,
"uiNumber": 1059,
"createdOn": "2026-09-11T12:19:00Z"
}
]The id of each company is the CLIENT_ID you use in every later request for that company.
Successful /wep/... responses return the object itself, with no wrapper. Some endpoints return 204 with no body. See Errors for the error format and status codes.
From first request to first payroll
This is the order most integrations follow. Each step links to the page that has the endpoint, fields and examples.
| Step | What you do | Where |
|---|---|---|
| 1 | Get an access token. | How to get API access |
| 2 | Create a company for your customer. | Create a company |
| 3 | Set up the company: tax setup, bank account and signatories. | Company Tax Setup, Company Bank Accounts, Company Signatories |
| 4 | Add the company's employees. | Create an employee |
| 5 | Complete each employee's tax setup. | Employee Tax Setup |
| 6 | Run payroll. | Run payroll |
| 7 | Stay in sync with webhooks. | Webhooks |
Before payroll can be run your company has to be KYC verified.
How a payroll run works
You run payroll with three calls:
- Start the run with
POST .../payroll. The response returns arunId. Calling it again while a run is in progress returns the same run. - Advance the run with
POST .../payroll/{runId}/next. Each call moves the run to its next processing step. The response shows the step incurrentProcStepDesc. - Finalize the run with
POST .../payroll/{runId}/finalize. This is the last call. It returns204with no body.
See Run payroll for the request and response fields and the behavior when there are no more steps to advance. For payrolls outside the regular schedule, see Off-cycle payroll. To correct a finalized payroll, see Void payroll.
Staying in sync with webhooks
You do not need to poll the API for changes. Register a webhook and Worklio sends a request to your URL when a matching event occurs, for example when an employee is created. You can register a webhook for one company or for every company your access token can reach, and you choose which categories of events trigger it: payroll, employee, company, or all.
Every delivery carries a WEP-Sign header. It holds the HMAC-SHA256 hex digest of the raw request body, using the webhook's key as the secret. Recompute it on your side to confirm the request came from Worklio. See Webhooks for registration and verification, and Webhook event types for the events.
Errors
Branch on the HTTP status code first:
| Status | Meaning |
|---|---|
2xx | Success. |
4xx | Fix the request. The cause is authentication, permissions, a missing resource, or invalid input. |
5xx | A server-side failure. Retry idempotent requests; report persistent failures. |
Error bodies are JSON with code, errorCode, message and validationErrors fields. A 401 has no body. See Errors for every status code, the body format and how to handle each one.
Sandbox and production
To test, register a developer account and sign in to the sandbox dashboard. The dashboard lists the companies on your developer account. It is empty until you create one. Sandbox credentials are shared, as described in How to get API access. While registered with us, you will also have your own demo and production environments available. Demo doesn't file real tax forms or move money.
Rate limits and idempotency
There are no real set rate limits because each of our partners has their own instance.
Where to go next
- How to get API access: developer account and access token.
- How to embed payroll in your product: the step-by-step build.
- Create a company: the first object you create.
- Run payroll: the three-call payroll run.
- Webhooks: get notified instead of polling.
Updated about 1 hour ago
