The WorkforceOS API lets your accounting software, spreadsheets or your own tools read your company's data, and webhooks tell them the moment something changes. It's in packages that include Public API and webhooks.
Keys
A Super Admin makes keys on the Integrations page. A key is shown once: copy it into your tool. Send it with every request:
curl https://app.workforceos.info/api/v1/employees \
-H "Authorization: Bearer wfos_your_key"
A key can read everything listed below for your company, so treat it like a password. Revoke it on the Integrations page if it's ever shared by mistake. Each key can make 120 requests a minute.
Endpoints
| Request | Returns |
|---|---|
GET /api/v1/employees | Current employees: id, code, name, email, role, job title, department, manager, joining date. No salaries. |
GET /api/v1/attendance?from=2026-10-01&to=2026-10-31 | Clock-ins and clock-outs on those Nepal days (up to 31 days), with worked minutes. |
GET /api/v1/leave?from=2026-10-01&to=2026-12-31&status=APPROVED | Leave overlapping those days (up to a year). Status is optional: PENDING, APPROVED or REJECTED. |
GET /api/v1/payslips?month=2026-10 | The approved payslips of a payroll month: basic, overtime, bonuses, tax, SSF, CIT, loan repayment and net pay, in NPR. |
Dates are YYYY-MM-DD; times are ISO 8601 in UTC. Lists return { "data": [...], "nextCursor": "..." }: ask again with &cursor= and that value for the next page, and use &limit= (up to 500) to change the page size.
Errors
Errors come back as { "error": "what went wrong" } with status 400 (a wrong value), 401 (missing or revoked key), 402 (your access has ended), 403 (not in your package) or 429 (too many requests; wait a minute).
Webhooks
Add a webhook on the Integrations page with your https address and the events you want: employee.created, leave.approved, leave.rejected and payroll.approved. We send a POST with a JSON body like { "event": "leave.approved", "createdAt": "...", "data": { ... } }, and a header X-WorkforceOS-Signature: sha256=.... Check it with the signing secret shown when you added the webhook:
import crypto from "node:crypto";
// body: the raw request body as a string; header: X-WorkforceOS-Signature
function isFromWorkforceOS(body, header, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex");
return header.length === expected.length && crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
Answer with any 2xx status within 5 seconds. "Send a test" on the Integrations page sends a ping event.
Questions or a missing endpoint? Write to contact@workforceos.info.