Builders · MCP

The Winslow MCP.

One server. Every Winslow capability. Connect Claude, ChatGPT, Cursor, Lovable, or any MCP-capable agent to the same API your admin UI uses — full read/write, gated by role, audited on every action.

Production MCP
What is the Winslow MCP?

One protocol, every Winslow capability.

The Winslow MCP server is a Model Context Protocol endpoint that exposes 185 first-class tools covering employees, payroll, benefits, documents, time off, approvals, custom properties, and your agent runtime. It uses the same authorization layer as the admin UI — agents inherit the role of the API key, not a separate "service" permission.

  • Full read/write — not a read-only wrapper around a public API
  • Workspace-scoped — API keys resolve workspace automatically
  • Per-field role gating — agents see and write what the key's role allows
  • Audit log — every agent action is a first-class event, exportable to your SIEM
  • Webhooks + events — agents can subscribe to hires, terminations, writes, comp changes
Connect

Two ways in, one server.

POST /api/mcp                      # Streamable HTTP
Authorization: Bearer <api-key>    # MCP API key, prefix wns_
mcp-session-id: <from response>    # echo back on every later request

MCP API key (wns_…) — for trusted backend and admin automation. The key acts as a workspace member, with that member's scopes.

OAuth 2.0 “Login with Winslow” — for anything user-facing, and the recommended default for third-party apps. Supports discovery, PKCE public clients, and RFC 7591 dynamic client registration.

Onboarding a brand-new company runs on a separate server with its own four tools — its endpoint and keys are not interchangeable with this one.

Authorization

Three checks, in order.

  1. Scope. Does the key or token hold a required scope? If not: AUTH_DENIED{kind:'scope'}.
  2. Relationship. Is the target record yours, a direct report's, or admin-visible? If not: AUTH_DENIED{kind:'relationship'}.
  3. Projection. Which columns come back — FULL, SELF, DIRECT_REPORT or PUBLIC. Responses name the projection in fieldVisibility.

Reading an employee who isn't you or your report returns the PUBLIC directory view, not an error — with a fieldVisibilityNote saying so. Errors across the surface: AUTH_DENIED, VALIDATION_ERROR, ENTITY_NOT_FOUND, BAD_REQUEST.

Each section below lists the scopes its tools need. A tool listing several accepts any one of them. Open Details on a tool for its exact scope, who can call it, and the server's own notes.

Tool reference

185 tools, organized by domain.

Every tool the production server advertises, in 31 sections. Required parameters come first; optional ones end in ?. Tools that change data are marked writes.

Last verified 2026-09-10 against the live server — every name below is checked against get_api_docs({ section: "matrix" }) on each build.

Workspace & Identity

Call these first: get_workspace confirms which workspace the key belongs to, get_me resolves the caller's own employeeRecordId before any employee-scoped tool.

ScopesNone — any workspace member

Tool
Description
Parameters
get_workspace
The workspace tied to your API key — id and name.
none
get_me
The user behind the key and their linked employeeRecordId. If it's null, find the record with list_employees.
none

Employee Management

Directory reads, record writes, and signup invites.

Scopesemployee:addemployee:manage-dataself:manage-data

Tool
Description
Parameters
get_employee
Any employee in the workspace, projected to what you may see — FULL, SELF, DIRECT_REPORT, or the PUBLIC directory view. A non-report read returns PUBLIC, not an error.
Details
Scope
employee:manage-data or self:manage-data
Who
Self, direct manager, or admin
Server
Self → EMPLOYEE columns; direct report → MANAGER columns; any other in-workspace record → PUBLIC projection (sensitive fields stripped); admin → full record. A non-report read returns the public projection, NOT an error — the response's `fieldVisibility` field labels which projection was applied (FULL / SELF / DIRECT_REPORT / PUBLIC), and PUBLIC responses carry a `fieldVisibilityNote` marking the record as a restricted directory view. The in-app UI does not open non-report profiles; MCP intentionally returns the directory-equivalent public view instead.
employeeRecordId
list_employees
The company directory — every employee, PUBLIC fields only. Defaults to active US_FULL_TIME + INT_FULL_TIME.
Details
Scope
employee:manage-data or self:manage-data
Who
Scope only — any holder, every record
employeeTypes
US_FULL_TIMEUS_CONTRACTORUS_VENDORINT_FULL_TIMEINT_CONTRACTOR
Server
Directory semantics: every workspace member sees ALL employee rows, including non-reports — but each row carries PUBLIC columns only (the same fields the in-app company directory shows), so no sensitive data is exposed. Use list_managed_employees for the richer self + direct-reports record set. Defaults to active US_FULL_TIME + INT_FULL_TIME; includeInactive/employeeTypes widen it.
employeeTypes?includeFutureStarts?includeInactive?includeTerminated?workspaceId?
list_managed_employees
Yourself plus your direct reports (admins: everyone), with the richer relationship-scoped fields. Mirrors the Manage Employees view.
Details
Scope
employee:manage-data or self:manage-data
Who
Self, direct manager, or admin
employeeTypes
US_FULL_TIMEUS_CONTRACTORUS_VENDORINT_FULL_TIMEINT_CONTRACTOR
Server
Columns are relationship-scoped per row: the actor's own row carries EMPLOYEE-visible columns, direct reports carry MANAGER-visible columns, admins see full records. Mirrors the REST route GET /api/employee-records/workspace/:id (same scoped service). Defaults to active US_FULL_TIME + INT_FULL_TIME; includeInactive/includeFutureStarts/includeTerminated/employeeTypes widen it.
employeeTypes?includeFutureStarts?includeInactive?includeTerminated?workspaceId?
create_employeewrites
Create an employee record with a linked Winslow user. The only way to set isTrial.
Details
Scope
employee:add
Who
Direct manager or admin
Note
essentials must include workEmail. customProperties is a JSON string array of { label, data }.
Server
WIN-668: a non-admin holding employee:add may only create an employee as their OWN direct report — the payload's system-managerId must equal the actor's employeeRecordId (enforced in createEmployeeRecordWithLinkedUserScoped). Admins/system-admins are unconstrained. Only MCP entry point that can set isTrial.
essentialscustomPropertiesisTrial?workspaceId?
update_employeewrites
Change only the fields you pass. Salary is system-salaryRate, title system-title, manager system-managerId. Field-level permissions apply.
Details
Scope
employee:manage-data or self:manage-data
Who
Self, direct manager, or admin
employeeType
US_FULL_TIMEUS_CONTRACTORUS_VENDORINT_FULL_TIMEINT_CONTRACTOR
Note
Returns { employeeRecordId, updated: true } — it does not echo the record back, so no sensitive fields leak.
Server
Field-level editability is enforced downstream by updateEmployeeRecordScoped (no separate auth in the MCP handler): salary/compensation fields require manager or admin. Only pass the fields to change — untouched fields are left as-is. Returns {employeeRecordId, updated:true} on success; does NOT echo the full record to avoid leaking sensitive fields.
employeeRecordIdavatarURL?customProperties?employeeType?workEmail?
invite_employee_to_winslowwrites
Email a signup invite, replacing any pending invite with a fresh one.
Details
Scope
employee:add
Who
Direct manager or admin
Server
Replaces any existing pending invite for the employee with a fresh one and sends the invitation email.
employeeRecordIdcustomMessage?
get_employee_invite_linkwrites
The signup URL for an employee who hasn't joined. Creates a pending invite if none exists; sends no email.
Details
Scope
employee:add
Who
Direct manager or admin
Server
Read-mostly but classified as mutate: returns the existing pending invite's signup URL, CREATING a pending invite when none exists (no email is sent).
employeeRecordId

Employee Documents

Winslow-stored employee documents, plus the unified Check / SPD document view.

Scopesemployee:manage-benefitsemployee:manage-documentsemployee:manage-payrollself:manage-benefitsself:manage-documentsself:manage-payroll

Tool
Description
Parameters
list_employee_documents
All Winslow documents on an employee record, optionally filtered by type.
Details
Scope
employee:manage-documents
Who
Self, direct manager, or admin
type
TERMINATIONLEAVEOTHER
employeeRecordIdtype?
get_employee_document
One document's metadata plus a publicLink to download it.
Details
Scope
employee:manage-documents
Who
Self, direct manager, or admin
employeeRecordIdemployeeDocumentId
find_employee_documents
Ranked search over one employee's documents by file name or agentData (e.g. "I9").
Details
Scope
employee:manage-documents
Who
Self, direct manager, or admin
type
TERMINATIONLEAVEOTHER
employeeRecordIdsearchQuerylimit?type?workspaceId?
begin_employee_document_uploadwrites
Preferred upload path for PDF, DOCX, or anything over 256 KB. Returns a 15-minute signed URL for a multipart POST (100 MB cap).
Details
Scope
employee:manage-documents or self:manage-documents
Who
Self, direct manager, or admin
type
TERMINATIONLEAVEOTHER
Note
Allowed extensions: pdf, doc, docx, md, png, jpg, jpeg, gif, webp. See the two-step upload guide below.
Server
Step 1 of the two-step upload: mints a 15-minute signed uploadUrl bound to the caller. Step 2 (multipart POST to the URL) uses the signed URL as auth and re-verifies current scope + relationship in the upload route handler.
employeeRecordIdfileNametype?workspaceId?
upload_employee_documentwrites
Upload a small file as base64 — 256 KB decoded max. Use begin_employee_document_upload for anything larger.
Details
Scope
employee:manage-documents or self:manage-documents
Who
Self, direct manager, or admin
type
TERMINATIONLEAVEOTHER
Server
Base64 payloads are capped at 256 KB decoded; larger files must use begin_employee_document_upload (two-step multipart flow, 100 MB cap).
employeeRecordIdfileNamefileBase64type?workspaceId?
get_employee_document_resource
A document as an MCP embedded resource (base64 blob + mimeType), up to 50 MB. No metadata.
Details
Scope
employee:manage-documents
Who
Direct manager or admin
Server
Uses the stricter 'manage' relationship message; the binary blob is gated more tightly than the text/metadata reads.
employeeRecordIdemployeeDocumentId
get_employee_document_content
Extracted content for agents without embedded-resource support: text for PDF/DOCX/DOC/MD/TXT, or PNG page images (max 10 pages).
Details
Scope
employee:manage-documents
Who
Self, direct manager, or admin
format
textimages
Note
A scanned PDF with little text returns a hint to retry with format=images.
employeeRecordIdemployeeDocumentIdformat
set_employee_document_validationwrites
Set a document's validation state and/or agentData. agentData is replaced wholesale, not merged.
Details
Scope
employee:manage-documents
Who
Self, direct manager, or admin
validation
validinvalidnull
employeeRecordIdemployeeDocumentIdvalidation?agentData?
get_employee_documents
One list across Check tax docs, Check filing forms, benefit SPDs and Winslow uploads.
Details
Scope
self:manage-documents or employee:manage-documents or self:manage-payroll or employee:manage-payroll or self:manage-benefits or employee:manage-benefits
Who
Self, direct manager, or admin
type
TAXPAYROLLSPDOTHER
Note
Each section is included only if you pass that section's own gate — sections you can't see are silently omitted, unless you request one explicitly.
Server
Per-section gates: TAX and PAYROLL need self:/employee:manage-payroll and have NO direct-manager path (self / employee:manage-payroll / admin only); SPD needs self:/employee:manage-benefits and OTHER needs self:/employee:manage-documents, both with the standard self-or-direct-report read relationship. The overall relationship column reflects the widest (SPD/OTHER) behavior.
employeeRecordIdtype?workspaceId?
get_employee_payroll_document
Download a Check document: tax (W-2, 1099) or filing (state/federal withholding forms).
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
type
taxfiling
Server
Bypass scope: employee:manage-payroll. No direct-manager path — W-2/1099 and withholding filings are sensitive PII. type=tax works for employees and contractors; type=filing requires a Check-enrolled W-2 employee.
employeeRecordIddocumentIdtypeworkspaceId?

Employee Benefits

Employee-facing reads over the CURRENT coverage timeline — the same data as the Employee Record Benefits tab.

Scopesemployee:manage-benefitsself:manage-benefits

Tool
Description
Parameters
get_employee_benefits
Current medical, dental and vision coverage: status, plan, carrier, tier and covered dependents.
Details
Scope
employee:manage-benefits or self:manage-benefits
Who
Self, direct manager, or admin
Server
self:manage-benefits is an alternative that satisfies the scope gate; the relationship gate (self/report/admin) still applies — it is NOT narrowed to the caller's own record in MCP the way the HTTP self route is.
employeeRecordIdworkspaceId?
list_employee_benefit_spds
Entry point for SPDs: lists the Summary Plan Documents for an employee's enrolled plans, each with an attachmentRef and a recommended flag.
Details
Scope
employee:manage-benefits or self:manage-benefits
Who
Self, direct manager, or admin
planTypes
MEDICALDENTALVISION
Note
Omit planTypes for all three. Pass an entry's attachmentRef to get_employee_benefit_spd_document.
employeeRecordIdplanTypes?workspaceId?
get_employee_benefit_spd_document
The extracted text of one SPD, by an attachmentRef from list_employee_benefit_spds. Paginate large documents with offset + maxChars.
Details
Scope
employee:manage-benefits or self:manage-benefits
Who
Self, direct manager, or admin
Note
With maxChars (alias limit) set, returns { totalChars, offset, returnedChars, hasMore, text }; advance offset by returnedChars until hasMore is false. Scanned PDFs return hint: scan_or_image_pdf. Replaces get_employee_benefit_spd, which returned base64 PDFs.
employeeRecordIdattachmentRefoffset?maxChars?limit?workspaceId?

Benefits Administration — Plan Catalog & Selection Lifecycle

Admin surface for the plan catalog and the stakeholder plan-selection review. Reads also accept the caller's own self:manage-benefits.

Scopesbenefits:manage-plansself:manage-benefits

Tool
Description
Parameters
list_benefit_plans
Every benefit plan in the workspace, any status.
Details
Scope
benefits:manage-plans or self:manage-benefits
Who
Scope only — any holder, every record
workspaceId?
get_benefit_plan
One benefit plan by id.
Details
Scope
benefits:manage-plans or self:manage-benefits
Who
Scope only — any holder, every record
planIdworkspaceId?
create_benefit_planwrites
Add a plan to the catalog (PENDING) — the first step of onboarding a plan. SBC/SPD files are uploaded in the UI.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planType
MEDICALDENTALVISION
Note
states: US state codes the plan covers — omit or leave empty for a national plan.
Server
First step of the onboarding recipe (see get_api_docs mcp section).
carrierIdbrokerIdnameplanTypecarrierPlanUrl?employerContribution?groupNumber?notes?planCode?policyNumber?sbcUrl?states?workspaceId?
update_benefit_planwrites
Change catalog fields or lifecycle status. ACTIVE / PRE_ACTIVE require groupNumber and policyNumber set first.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planType
MEDICALDENTALVISION
status
PENDINGVERIFIEDNOT_SELECTEDSELECTEDPRE_ACTIVEACTIVEINACTIVE
planIdbrokerId?carrierId?carrierPlanUrl?employerContribution?groupNumber?name?notes?planCode?planType?policyNumber?sbcUrl?states?status?workspaceId?
delete_benefit_planwrites
Delete a PENDING or NOT_SELECTED plan with no elections and no offerings.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planIdworkspaceId?
finalize_plan_selectionwrites
Mark each VERIFIED plan SELECTED or NOT_SELECTED. Auto-closes an OPEN selection period.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
waivedTypes
MEDICALDENTALVISION
Note
contributions: employer contribution % keyed by plan id. waivedTypes: plan types deliberately left with no selection.
Server
Auto-closes an OPEN plan selection period.
selectedPlanIdscontributions?waivedTypes?workspaceId?
list_plan_offerings
Plan offerings (rate history) for exactly one of a plan or a coverage period.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
Note
Pass exactly one of planId or coveragePeriodId.
planId?coveragePeriodId?workspaceId?
get_plan_offering
One plan offering by id.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planOfferingId
create_plan_offeringwrites
A priced coverage snapshot of a plan. Attaching a coverage period requires the plan to be PRE_ACTIVE or ACTIVE.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
Note
The workspace is derived from planId. quotingData takes composite tiers (employeeOnly / employeeSpouse / employeeChildren / family) or age-banded rates. Omit coveragePeriodId for a standalone quote.
Server
Workspace is derived from planId, not a client-supplied workspaceId (mirrors resolveWorkspaceFromCreateOfferingBody in plan-offerings.routes.ts).
planIdcoverageData?coveragePeriodId?effectiveFrom?effectiveTo?employerContribution?quotingData?
update_plan_offeringwrites
Change an offering's rates or coverage data. Blocked while its coverage period is OPEN.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planOfferingIdcoverageData?effectiveFrom?effectiveTo?employerContribution?quotingData?
delete_plan_offeringwrites
Delete an offering. Blocked once it has elections or its period is past DRAFT.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planOfferingId
copy_plan_offerings_from_previouswrites
Roll a plan's most recent offering into a new coverage period, using that period's dates.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
planIdcoveragePeriodId
get_plan_selection_status
The workspace's plan-selection status: DRAFT, OPEN, CLOSED, or null if never started.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
create_plan_selectionwrites
Start a plan-selection period (DRAFT). Needs a VERIFIED plan and no active period.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
open_plan_selectionwrites
Open selection for stakeholder review (DRAFT → OPEN).
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
close_plan_selectionwrites
Close selection (OPEN → CLOSED). Usually followed by finalize_plan_selection.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
reset_plan_selectionwrites
Reset selection back to DRAFT. Close an OPEN period first.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
get_benefits_configuration
Step 0 of benefits onboarding: the hasFullCensus flag, created on first read.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
workspaceId?
update_benefits_configurationwrites
Set the hasFullCensus flag, which affects eligibility calculations.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
hasFullCensusworkspaceId?
list_brokers
All brokers. Winslow-managed and cross-workspace — read-only; there is no create or update tool.
Details
Scope
benefits:manage-plans
Who
Scope only — any holder, every record
Server
Brokers are read-only via MCP — no create/update tool exists.
none

Benefits Administration — Coverage Periods, Enrollment & Elections

Open-enrollment windows, per-employee election state, and finalization + sync to Check. The employee-facing election tools also accept self:manage-benefits on the caller's own record.

Scopesbenefits:manage-oebenefits:manage-qleemployee:manage-benefitsself:manage-benefits

Tool
Description
Parameters
list_coverage_periods
Every coverage (open enrollment) period, any status.
Details
Scope
benefits:manage-oe or self:manage-benefits
Who
Scope only — any holder, every record
workspaceId?
get_coverage_period
One coverage period plus its enrollment summary — election counts by plan type and status.
Details
Scope
benefits:manage-oe or self:manage-benefits
Who
Scope only — any holder, every record
coveragePeriodIdworkspaceId?
create_coverage_periodwrites
A new DRAFT period: the OE window and the coverage dates that follow it.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
Note
coverageEffectiveDate must be the 1st or 15th of a month and strictly after endDate. No overlap with an existing period's OE or coverage window.
startDateendDatecoverageEffectiveDatecoverageEndDateworkspaceId?
update_coverage_periodwrites
Change a DRAFT or OPEN period's dates. Once OPEN, only endDate / coverageEndDate can move, and only later.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
coveragePeriodIdcoverageEffectiveDate?coverageEndDate?endDate?startDate?workspaceId?
delete_coverage_periodwrites
Delete a coverage period. Blocked if any eligible election is FINALIZED.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
coveragePeriodIdworkspaceId?
activate_open_enrollmentwrites
Open enrollment (DRAFT/CLOSED → OPEN). Creates PENDING elections for every eligible employee × offered plan type.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
Server
Creates PENDING elections for every eligible employee × offered plan type.
coveragePeriodIdworkspaceId?
close_open_enrollmentwrites
Close the enrollment window (OPEN → CLOSED) — the step before broker import and verification.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
coveragePeriodIdworkspaceId?
get_enrollment_tracking
Per-employee OE progress: submission status and projected costs.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
coveragePeriodIdworkspaceId?
send_enrollment_reminderswrites
Email a reminder to a set of employees. Returns { sent, failed } — one failure doesn't fail the call.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
Server
Returns {sent, failed} — individual send failures do not fail the whole call.
coveragePeriodIdemployeeRecordIdssubjectbodyworkspaceId?
get_employee_enrollment
An employee's OE data: available plans, current elections, dependents, progress. Defaults to the current period.
Details
Scope
self:manage-benefits or employee:manage-benefits or benefits:manage-oe or benefits:manage-qle
Who
Self, or a bypass scope — no manager path
Server
Same bypass nuance as get_qle_enrollment: employee:manage-benefits or benefits:manage-oe ONLY — benefits:manage-qle satisfies the scope gate but does not bypass ownership.
employeeRecordIdcoveragePeriodId?workspaceId?
get_election_history
An employee's full election history, grouped by coverage period, plus dependents.
Details
Scope
self:manage-benefits or employee:manage-benefits or benefits:manage-oe or benefits:manage-qle
Who
Self, or a bypass scope — no manager path
Server
Same bypass nuance as get_qle_enrollment: employee:manage-benefits or benefits:manage-oe ONLY, not benefits:manage-qle.
employeeRecordIdworkspaceId?
update_employee_electionwrites
Elect a plan and coverage tier on a PENDING/ELECTED election. Only while the period is OPEN.
Details
Scope
self:manage-benefits or benefits:manage-oe
Who
Self, or a bypass scope — no manager path
coverageTier
EMPLOYEE_ONLYEMPLOYEE_SPOUSEEMPLOYEE_CHILDRENFAMILY
Server
Bypass is benefits:manage-oe ONLY — employee:manage-benefits is view-only and does not bypass write ownership here (AUTHORIZATION.md §10).
electionIdplanIdcoverageTierdependentIds?workspaceId?
waive_employee_electionwrites
Decline coverage for this plan type. Only while the period is OPEN.
Details
Scope
self:manage-benefits or benefits:manage-oe
Who
Self, or a bypass scope — no manager path
Server
Bypass is benefits:manage-oe ONLY (same as update_employee_election).
electionIdwaiveReason?workspaceId?
clear_employee_electionwrites
Reset an election to PENDING, clearing plan, tier and dependents. Only while OPEN.
Details
Scope
self:manage-benefits or benefits:manage-oe
Who
Self, or a bypass scope — no manager path
Server
Resets the election back to PENDING. Bypass is benefits:manage-oe ONLY (same as update_employee_election).
electionIdworkspaceId?
submit_employee_enrollmentwrites
Submit an enrollment once every plan type is ELECTED or WAIVED. Requires a base64 PNG signature.
Details
Scope
self:manage-benefits or benefits:manage-oe
Who
Self, or a bypass scope — no manager path
Note
signature: a base64-encoded PNG of the employee's signature, 2 MB decoded max.
Server
Requires a base64 PNG signature. Bypass is benefits:manage-oe ONLY (same as update_employee_election).
employeeRecordIdcoveragePeriodIdsignatureworkspaceId?
list_period_elections
Every election in a coverage period, across all eligible employees — the broker-import / verification working set.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
Server
The broker-import / verification working set (admin-only).
coveragePeriodIdworkspaceId?
finalize_open_enrollmentwrites
Finalize a CLOSED period: CONFIRMED elections become FINALIZED and coverage syncs to Check. Call once to preview blockers.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
Note
acknowledged must be true. Blockers — unconfirmed elections, unaccepted broker-import diffs, missing carrier member ids, carrier declines — come back as the error payload.
Server
Marks CONFIRMED elections FINALIZED and syncs coverage to Check. Preview blockers by calling it first — they're returned as the error payload.
coveragePeriodIdacknowledgedworkspaceId?
admin_update_electionwrites
Admin hand-edit of an election: carrier member id, premiums, plan/tier/dependents, coverage dates, carrier data.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
coverageTier
EMPLOYEE_ONLYEMPLOYEE_SPOUSEEMPLOYEE_CHILDRENFAMILY
Note
Premium recalculates automatically unless employeePremium / employerContribution are given explicitly (0–99999).
Server
Admin hand-edit (carrier member id, premiums, plan/tier/dependents, coverage dates, carrier data) — no per-employee ownership check, scope alone gates it.
coveragePeriodIdelectionIdcarrierEnrollmentData?carrierMemberId?coverageEffectiveDate?coverageEndDate?coverageTier?dependentIds?employeePremium?employerContribution?note?planId?workspaceId?
set_election_statuswrites
Admin override of an election's status — e.g. CONFIRMED after carrier verification.
Details
Scope
benefits:manage-oe
Who
Scope only — any holder, every record
status
PENDINGELECTEDIN_REVIEWWAIVEDCONFIRMEDFINALIZED
Note
WAIVED → ELECTED needs a planId. CONFIRMED needs a planId + carrierMemberId (or a waiveReason if waiving).
coveragePeriodIdelectionIdstatusworkspaceId?

Benefits Administration — Qualifying Life Events (QLE)

The QLE side-channel, independent of the OE lifecycle. QLE elections are never written by an admin tool — they stay employee-attested.

Scopesbenefits:manage-oebenefits:manage-qleemployee:manage-benefitsself:manage-benefits

Tool
Description
Parameters
preview_life_event_requirements
The documents, data entry, attestations and filing window for an event type + changes. Stateless.
Details
Scope
self:manage-benefits or benefits:manage-qle
Who
Any workspace member
eventType
MARRIAGEDIVORCEBIRTH_ADOPTIONDEATH_OF_DEPENDENTLOSS_OF_COVERAGEGAIN_OF_COVERAGEEMPLOYMENT_STATUS_CHANGERELOCATIONAGING_OUTCOURT_ORDEROTHER
changeActions
ADD_DEPENDENTREMOVE_DEPENDENTENROLL_IN_COVERAGECANCEL_COVERAGECHANGE_PLANCHANGE_COVERAGE_LEVEL
eventTypechangeActions
file_life_event_requestwrites
File a QLE. Employees file only for themselves; a QLE admin may file for anyone. Supporting documents are uploaded in the UI.
Details
Scope
self:manage-benefits or benefits:manage-qle
Who
Self or admin only — no manager path
eventType
MARRIAGEDIVORCEBIRTH_ADOPTIONDEATH_OF_DEPENDENTLOSS_OF_COVERAGEGAIN_OF_COVERAGEEMPLOYMENT_STATUS_CHANGERELOCATIONAGING_OUTCOURT_ORDEROTHER
changeActions
ADD_DEPENDENTREMOVE_DEPENDENTENROLL_IN_COVERAGECANCEL_COVERAGECHANGE_PLANCHANGE_COVERAGE_LEVEL
affectedPlanTypes
MEDICALDENTALVISION
Server
Bypass: isAdmin, isSystemAdmin (checked directly), or benefits:manage-qle — mirrors isQleAdmin() in life-events.routes.ts / benefits-qle.tools.ts. Cannot attach supporting documents (UI-only upload).
employeeRecordIdeventTypeeventDatedescriptionchangeActionsaffectedPlanTypesrequirementsData?workspaceId?
list_life_event_requests
Every QLE request in the workspace.
Details
Scope
benefits:manage-qle
Who
Admins only
workspaceId?
list_employee_life_event_requests
One employee's QLE requests. Employees see only their own.
Details
Scope
self:manage-benefits or benefits:manage-qle
Who
Self or admin only — no manager path
Server
Same bypass as file_life_event_request: isAdmin/isSystemAdmin/benefits:manage-qle.
employeeRecordIdworkspaceId?
get_life_event_request
One QLE request. Private to the filer and QLE admins.
Details
Scope
self:manage-benefits or benefits:manage-qle
Who
Self or admin only — no manager path
Server
Same bypass as file_life_event_request: isAdmin/isSystemAdmin/benefits:manage-qle. A QLE request is private to the filer.
lifeEventRequestIdworkspaceId?
update_life_event_request_statuswrites
Change a QLE's status. APPROVED opens the employee's QLE window and drafts elections for the affected plan types.
Details
Scope
benefits:manage-qle
Who
Admins only
status
SUBMITTEDAPPROVEDENROLLMENT_SUBMITTEDDENIEDCOMPLETEDARCHIVED
Server
Approving (SUBMITTED → APPROVED) opens the employee's QLE enrollment window and creates draft elections for the affected plan types.
lifeEventRequestIdstatusnotes?workspaceId?
get_qle_enrollment
QLE enrollment data for an APPROVED (or later) request: plans, elections, dependents, progress.
Details
Scope
self:manage-benefits or employee:manage-benefits or benefits:manage-oe or benefits:manage-qle
Who
Self, or a bypass scope — no manager path
Server
Bypass is employee:manage-benefits or benefits:manage-oe ONLY — benefits:manage-qle satisfies the scope gate above but does NOT bypass ownership here (mirrors denyUnlessReadOwnershipOrBenefitsViewer; the isAdmin/isSystemAdmin flags are not consulted).
employeeRecordIdlifeEventRequestIdworkspaceId?

Benefit Adjustments

Overrides to an employee's benefit deduction amounts. ONGOING changes the standing Check benefit; ONE_TIME overrides a single payroll.

Scopesemployee:manage-benefitspayroll:manage-payrolls

Tool
Description
Parameters
list_benefit_adjustments
All adjustments in the workspace, or the ONE_TIME adjustments on one Check payroll.
Details
Scope
employee:manage-benefits or payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
Without checkPayrollId you need employee:manage-benefits; payroll:manage-payrolls alone only unlocks the per-payroll view.
Server
The dispatcher gate is any-of; the handler adds a second gate so payroll:manage-payrolls alone only unlocks the per-payroll view (mirrors the REST route split).
checkPayrollId?employeeRecordId?workspaceId?
get_benefit_adjustment
One adjustment with employee fields, election and payroll summaries, and canDelete.
Details
Scope
employee:manage-benefits
Who
Scope only — any holder, every record
benefitAdjustmentId
create_benefit_adjustmentwrites
Adjust a full-time employee's FINALIZED election — ONGOING (standing) or ONE_TIME (one payroll).
Details
Scope
employee:manage-benefits or payroll:manage-payrolls
Who
Scope only — any holder, every record
adjustmentType
ONGOINGONE_TIME
Note
See the benefit adjustment rules below.
employeeRecordIdbenefitElectionIdadjustmentTypeemployeeAmountcompanyAmountcheckPayrollId?workspaceId?
update_benefit_adjustmentwrites
Change an adjustment's election, amounts or payroll. The ONGOING / ONE_TIME type can't change.
Details
Scope
employee:manage-benefits or payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
The adjustment type (ONGOING vs ONE_TIME) cannot be changed.
benefitAdjustmentIdbenefitElectionId?checkPayrollId?companyAmount?employeeAmount?
delete_benefit_adjustmentwrites
Delete an adjustment. ONGOING restores the election's premium; ONE_TIME only while the payroll is draft or pending.
Details
Scope
employee:manage-benefits or payroll:manage-payrolls
Who
Scope only — any holder, every record
benefitAdjustmentId

Payroll — Runs & Lifecycle

Create, refresh, calculate, approve and reopen payroll runs. approve_payroll and reopen_payroll need the separate payroll:approve scope — money moves on approve.

Scopespayroll:approvepayroll:manage-payrolls

Tool
Description
Parameters
list_payrolls
Payroll summaries for the workspace: id, name, type, status, payday, period and approval deadline.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
timeframe
upcominghistory
Note
Needs a workspace connected to Check payroll. Explicit paydayAfter / paydayBefore win over timeframe.
Server
Returns curated summaries (payrollId, name, type, status, payday, period, approvalDeadline) — no Check company id or raw pass-through.
limit?paydayAfter?paydayBefore?timeframe?workspaceId?
get_payroll
A curated, always-current PayrollView. Stale drafts are rebuilt and recalculated before returning; approved and paid runs come back as-is.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
Keyed by Winslow employeeRecordIds — no Check ids. Includes totals, per-employee pay breakdowns, contractors, and a freshness block reporting what the server did before returning.
Server
Returns a curated PayrollView — Winslow employee record ids + names only; no Check company/employee/contractor/item/bank ids, only UI-visible totals and columns. Freshness guarantee: dirty draft payrolls are auto-refreshed and uncalculated drafts auto-calculated before returning; errors instead of returning stale data. Foreign payrolls read as ENTITY_NOT_FOUND.
payrollIdworkspaceId?
create_next_regular_payrollwrites
Create the next regular payroll on the pay schedule, load employees and calculate taxes.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
Fails with 6+ upcoming payrolls or no future payday. Returns refreshError / calculationError instead of failing if those later steps break.
Server
Same next-payday rules as the Pay Upcoming UI (winslow-core pickNextPayday). Emits payroll-run.create; runs a full item refresh + calculation and returns a curated PayrollView (refreshError/calculationError are returned instead of failing when those steps break).
workspaceId?
rename_payrollwrites
Set a payroll's display name.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Stores the name in Check payroll metadata.name.
payrollIdnameworkspaceId?
calculate_payrollwrites
Force a tax recalculation without approving — the UI's preview step. No money moves.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
get_payroll already calculates when needed; use this only to force a fresh run.
Server
Triggers Check preview calculation (no money movement, no approval). Returns a curated PayrollView (see get_payroll).
payrollIdworkspaceId?
refresh_payrollwrites
Rebuild items from the current roster — earnings, adjustments, expenses, deductions, leave, exclusions — then recalculate. The heaviest payroll call.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
Termination off-cycles are left untouched; they're hand-built.
Server
Rebuilds items from the roster (adjustments, expenses, leave proration, exclusions), then recalculates and returns a curated PayrollView. Termination off-cycles are left untouched. Heaviest payroll operation.
payrollIdworkspaceId?
refresh_payroll_itemswrites
Rebuild a payroll's Check line items from Winslow state. Call after exclusions or reimbursement/adjustment changes.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
The selected*RecordIds params are off-cycle only and replace membership. Zero-pay employees come back as winslow-shell-* rows and are never sent to Check.
Server
Rebuilds Check line items from Winslow state. Zero-pay employees come back as winslow-shell-* display rows and are never sent to Check.
payrollIdselectedContractorRecordIds?selectedEmployeeRecordIds?workspaceId?
get_payroll_refresh_status
Whether a payroll needs refresh_payroll before it can be trusted or approved.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
payrollIdworkspaceId?
get_payroll_comparison
Per-employee deltas against the last paid regular payroll, plus new/removed employees and totals. Slow on large rosters.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Note
previousPayrollId is null when no paid regular baseline exists.
Server
Auto-refreshes/calculates the current payroll first. Comparison rows are keyed by employeeRecordId + name (no Check employee/contractor ids). Baseline is the most recent paid regular payroll (winslow-core getPreviousPayrollFromList); previousPayrollId is null when none exists.
payrollIdworkspaceId?
get_payroll_taxes
Employee-paid and company-paid tax lines per employee, plus aggregate totals. Always current.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Auto-refreshes/calculates the payroll first (freshness guarantee). Per-employee rows are keyed by employeeRecordId + name (no Check employee ids). Employee-payer vs company-payer split matches the payroll preview UI (missing payer field = employee).
payrollIdworkspaceId?
approve_payrollwrites
Approve a payroll for processing. Money moves after this.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Note
Needs payroll:approve, deliberately separate from payroll:manage-payrolls — give it only to signers. Check enforces the deadline and status. Blocked while billing is pre-billing or past its grace window.
Server
MONEY MOVES. payroll:approve is deliberately separate from payroll:manage-payrolls; assign it only to signers (2026-08 decision extends the scope to MCP under the same gate as the REST approve route). Emits payroll-run.approve. Returns a curated PayrollView. Billing-blocked approvals also fire a personal billing-payroll-blocked notification (claim-deduped per payroll per day) and never move money — in-grace approves normally, matching the REST route.
payrollIdworkspaceId?
reopen_payrollwrites
Return an approved payroll to draft, before Check's reopen deadline.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Server
Emits payroll-run.reopen. Returns a curated PayrollView.
payrollIdworkspaceId?
set_payroll_employee_exclusionwrites
Exclude an employee from one payroll run, or add them back. Idempotent.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
action
excludeinclude
Server
Per-payroll exclusion via PayrollDetail.removeEmployeeRecordIds; action is 'exclude' or 'include'. Idempotent (excluding an already-excluded employee is a no-op).
payrollIdemployeeRecordIdactionworkspaceId?

Payroll — Off-Cycle & Termination Pay

General off-cycle runs, and the final-pay off-cycle attached to a termination.

Scopesemployee:terminatepayroll:manage-payrolls

Tool
Description
Parameters
get_offcycle_payroll_payment_constraints
Payment-method rules for a payday: 3-business-day direct-deposit lead time, drop-dead date, allowed methods.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Returns direct-deposit lead time (3 business days), drop-dead date, and allowed payment methods for a payday.
payday
create_offcycle_payrollwrites
A general off-cycle payroll with UI-equivalent validation of payment method against payday.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
paymentMethod
DIRECT_DEPOSITCHECKBANK_TRANSFER
employeeMode
allselect
Note
With employeeMode=select, only the listed ids are paid; everyone else is recorded as excluded.
Server
Optional employeeRecordIds subset is persisted as PayrollDetail exclusions (all other active employees). Emits payroll-run.create; runs a full item refresh + calculation and returns a curated PayrollView.
namepaydaypaymentMethodapplyBenefits?applyPostTaxDeductions?employeeMode?employeeRecordIds?contractorRecordIds?workspaceId?
update_offcycle_payrollwrites
Change a draft general off-cycle's name, options or payment method. Not for termination off-cycles.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
paymentMethod
DIRECT_DEPOSITCHECKBANK_TRANSFER
Server
Updates draft general off-cycle payroll metadata/options and re-refreshes items when payment method or options change.
payrollIdapplyBenefits?applyPostTaxDeductions?name?paymentMethod?workspaceId?
delete_offcycle_payrollwrites
Delete a draft general off-cycle payroll. Not for termination off-cycles.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Deletes draft general off-cycle payrolls; clears PayrollDetail and invoice links first.
payrollIdworkspaceId?
create_termination_payrollwrites
Create the final-pay off-cycle for a termination that doesn't have one: prorated salary, plus optional severance and PTO.
Details
Scope
employee:terminate
Who
Direct manager or admin
Note
Every optional field defaults to what the termination record holds. Deleting a termination payroll stays REST/UI-only.
Server
For terminations recorded without a final-pay run (terminate_employee createOffcyclePayroll:false or a deleted off-cycle). Prorated salary comes from the effective salary at the termination date; severance/PTO default to the termination record. Deleting a termination payroll remains REST/UI-only.
terminationIdpayrollDate?severanceAmount?payOutPto?ptoPayoutAmount?ptoPayoutHours?workspaceId?

Payroll — Expenses & Reimbursements

Two related surfaces: *_payroll_expense (employee expense rows) and *_payroll_reimbursement (Winslow reimbursements on a payroll). Both mark the payroll dirty — follow with refresh_payroll.

Scopespayroll:manage-adjustmentspayroll:manage-payrolls

Tool
Description
Parameters
list_payroll_expenses
Expenses for the workspace, one payroll, or one employee.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
Note
One filter applies, checked in order: payrollId, then employeeRecordId, then the whole workspace.
employeeRecordId?payrollId?workspaceId?
add_payroll_expensewrites
Add an expense to an employee on a payroll. It lands on the items at the next refresh.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
Server
Marks the workspace payroll-dirty; the expense lands on items at the next refresh. Emits payroll-reimbursement.create at the service layer.
payrollIdemployeeRecordIdamountdescriptioncode?note?workspaceId?
remove_payroll_expensewrites
Remove an expense. Run refresh_payroll to update the items.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
Server
Marks the workspace payroll-dirty. Emits payroll-reimbursement.delete at the service layer.
expenseIdworkspaceId?
list_payroll_reimbursements
Winslow reimbursements on a payroll — the source of truth, even before Check has a line item.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Winslow is the source of truth for reimbursements, so this returns rows even when Check has no line item yet.
payrollIdworkspaceId?
create_payroll_reimbursementwrites
Add a reimbursement and rebuild the items. Works for $0-salary employees.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Writes the Winslow record then rebuilds Check items, which materializes a payroll item for a $0-salary employee.
payrollIdemployeeRecordIdamountdescriptioncode?note?workspaceId?
update_payroll_reimbursementwrites
Change a reimbursement and rebuild the items so the new amount reaches Check.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Updates the Winslow record then rebuilds Check items so the new amount reaches Check.
reimbursementIdamount?code?description?note?workspaceId?
delete_payroll_reimbursementwrites
Delete a reimbursement and rebuild the items. An employee with nothing left payable returns to a shell row.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Deletes the Winslow record then rebuilds Check items; an employee with nothing left payable returns to a shell row.
reimbursementIdworkspaceId?

Payroll — Pay Stubs

Employee-facing and admin-facing pay stub reads.

Scopesemployee:manage-payrollpayroll:manage-payrollsself:manage-payroll

Tool
Description
Parameters
get_pay_stubs
An employee's pay stubs, optionally filtered by payday. 25 per page.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
Note
Contractors are refused — they have no pay stubs.
Server
Bypass scope: employee:manage-payroll (NOT the run-payroll scope). No direct-manager path — pay stubs stay self + payroll-admin + admin only. Contractors are refused (no pay stubs).
employeeRecordIdendDate?limit?offset?startDate?workspaceId?
get_pay_stub
One employee's stub on a specific payroll: earnings, taxes, deductions and totals.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
Server
Bypass scope: employee:manage-payroll. No direct-manager path. The stub lookup is scoped to the target employee, so a foreign payrollId reads as not-found. Stub sanitized (void_of/voided_by stripped).
employeeRecordIdpayrollIdworkspaceId?
search_pay_stubs
The admin search surface over one employee's stubs, with payday filtering and pagination.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
Server
Same auth model and backing service as get_pay_stubs — provided as the admin-facing search surface. Bypass scope: employee:manage-payroll. No direct-manager path. Stubs sanitized (void_of/voided_by stripped).
employeeRecordIdstartDate?endDate?offset?limit?workspaceId?
list_payroll_paystubs
Every stub on a processed payroll. Drafts have none. One Check call per employee, so slow on large rosters.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Run surface (whole-payroll view) — gated on the run-payroll scope, unlike the per-employee stub tools. Entries are keyed by employeeRecordId + name; stubs sanitized (void_of/voided_by stripped). One Check call per employee (slow on large rosters).
payrollIdworkspaceId?

Payroll — Configuration, Approval Settings & Tax Parameters

Workspace payroll configuration, auto-approval behavior, and read-only Check tax parameters.

Scopesemployee:manage-payrollpayroll:approvepayroll:manage-payrollsself:manage-payroll

Tool
Description
Parameters
get_payroll_config
The Check company (processing status, start date) and its pay schedules.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
workspaceId?
get_payroll_signatory
The people authorized to sign payroll filings with Check.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
workspaceId?
list_workplaces
Check workplaces — the registered work locations used for tax jurisdiction.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
workspaceId?
get_company_tax_parameters
Company tax parameters: federal EIN, state account numbers, deposit schedules, unemployment rates.
Details
Scope
payroll:manage-payrolls
Who
Scope only — any holder, every record
Server
Values include sensitive identifiers (EIN, state account numbers).
workspaceId?
get_employee_tax_parameters
One employee's filing status, withholding allowances and additional withholding.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
Server
Sensitive withholding data — same gate as pay stubs (bypass scope employee:manage-payroll, no manager path). Cross-workspace ids read as not-found.
employeeRecordIdworkspaceId?
get_payroll_approval_settings
Workspace auto-approval settings for regular, termination and off-cycle payrolls, and the comparison gate.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Server
Workspace-level settings only; does not require a Check company (no per-payroll lookup). Includes the comparison-gate autoApproveMatchMode plus autoApproveDeviationPercent/autoApproveDeviationAmount.
workspaceId?
update_payroll_approval_settingswrites
Change any auto-approval setting. Omitted fields keep their value.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
autoApproveMatchMode
INVOICES_MUST_MATCHSALARIES_ONLYPERCENT_DEVIATIONDOLLAR_DEVIATIONALWAYS_APPROVE
Note
Enabling any auto-approve toggle is blocked while billing is pre-billing. A comparison-based mode needs at least one paid regular payroll to compare against. Pass null to clear a deviation.
Server
Only the fields present in the request are changed (booleans, autoApproveMatchMode, autoApproveDeviationPercent, autoApproveDeviationAmount — null clears a deviation); workspace-level, does not require a Check company. Enabling autoApproveRegular/Termination/OffCycle is blocked while billing status is pre-billing.
approveWithPayrollIssues?approveWithUnenrolledEmployees?autoApproveDeviationAmount?autoApproveDeviationPercent?autoApproveMatchMode?autoApproveOffCycle?autoApproveRegular?autoApproveTermination?workspaceId?
get_payroll_auto_approve
Whether regular payrolls auto-approve, plus the full settings. A daily 2am job does the approving.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Server
Returns available:true plus the full PayrollApprovalSettingsValues; enabled mirrors autoApproveRegular. Workspace-level; does not require a Check company.
workspaceId?
set_payroll_auto_approvewrites
Turn regular-payroll auto-approve on or off. When on, money moves without further human action.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Note
Blocked while billing is pre-billing. For finer-grained toggles use update_payroll_approval_settings.
Server
Persists autoApproveRegular (accepted:true); newly created payrolls are stamped from this setting. Finer-grained toggles (including match-mode and deviation) live on update_payroll_approval_settings. Enabling is blocked while billing status is pre-billing.
enabledworkspaceId?
set_payroll_auto_approve_overridewrites
Override auto-approve for one payroll run. Only while it's still a draft.
Details
Scope
payroll:approve
Who
Scope only — any holder, every record
Server
Per-payroll override of the workspace auto-approve default; only settable while the payroll is still in draft (pre-approval).
payrollIdautoApproveworkspaceId?

Payroll — Employee Status

Per-employee payroll enrollment and upcoming-pay lookups.

Scopesemployee:manage-payrollself:manage-payroll

Tool
Description
Parameters
get_employee_payroll_status
Check enrollment status: onboarding steps, SSN and payment-method substeps, roster eligibility. The only per-employee payroll tool managers can call.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self, direct manager, or admin
Note
SSN comes back masked, last 4 only. Unenrolled employees return { enrolled: false }, not an error.
Server
The only per-employee payroll tool with a direct-manager path (allowDirectManager opt-in — enrollment status is manager-visible summary data). SSN is returned masked (last-4 only, WIN-676). Unenrolled employees return {enrolled:false}, not an error.
employeeRecordIdworkspaceId?
get_employee_upcoming_payroll
The employee's nearest upcoming draft or pending payroll item: gross, net, taxes and earnings.
Details
Scope
self:manage-payroll or employee:manage-payroll
Who
Self or admin only — no manager path
Server
Bypass scope: employee:manage-payroll. No direct-manager path (upcoming pay amounts are compensation data).
employeeRecordIdworkspaceId?

Payroll Adjustments

Recurring adjustment templates and their per-payroll instances. Every tool here needs payroll:manage-adjustments — scope-only, no per-record relationship check.

Scopespayroll:manage-adjustments

Tool
Description
Parameters
list_payroll_adjustment_templates
Recurring rules: who gets paid what, and on which runs.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
Note
See the template enums and the $150 gym-supplement example below.
workspaceId?
get_payroll_adjustment_template
One template by id.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
templateId
create_payroll_adjustment_templatewrites
Create a recurring adjustment rule.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
targetType
EMPLOYEE_TYPEEMPLOYEE_LISTDEPARTMENT
recurrenceType
ONE_TIMEMONTHLYFIRST_HALFSECOND_HALF
amountType
FIXED_ALLASSIGNED_PER_PERSONCUSTOM_REQUIRED
Note
checkPayrollItemType is a Check earning type, e.g. bonus or reimbursement. assignedAmounts items are { employeeRecordId, amount }.
nametargetTyperecurrenceTypeamountTypecheckPayrollItemTypeactiveassignedAmounts?blocking?departments?description?fixedAmount?oneTimeOnPayroll?targetEmployeeIds?targetEmployeeTypes?workspaceId?
update_payroll_adjustment_templatewrites
Change any template fields.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
templateIdactive?amountType?assignedAmounts?blocking?checkPayrollItemType?departments?description?fixedAmount?name?oneTimeOnPayroll?recurrenceType?targetEmployeeIds?targetEmployeeTypes?targetType?
delete_payroll_adjustment_templatewrites
Delete a template by id.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
templateId
list_payroll_adjustments
Adjustment instances, optionally filtered by payroll and/or employee.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
checkPayrollId?employeeRecordId?workspaceId?
get_payroll_adjustment
One adjustment instance by id.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
adjustmentId
create_payroll_adjustmentwrites
An adjustment for one employee, optionally linked to a template and/or a payroll.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
employeeRecordIdnameamountcheckPayrollItemTypecheckPayrollId?notes?payrollAdjustmentTemplateId?status?workspaceId?
update_payroll_adjustmentwrites
Change an adjustment instance. Contractor reimbursements re-sync to Check when the amount changes.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
adjustmentIdamount?checkPayrollId?checkPayrollItemType?name?notes?overridden?status?
delete_payroll_adjustmentwrites
Delete an adjustment instance, removing any linked one-off Check earnings.
Details
Scope
payroll:manage-adjustments
Who
Scope only — any holder, every record
adjustmentId

Time Off & Holidays

Time-off requests and the company holiday calendar.

Scopesself:manage-requeststime-off:manage-requests

Tool
Description
Parameters
list_time_off
PENDING and APPROVED time-off requests. Defaults to those overlapping the current month.
Details
Scope
time-off:manage-requests
Who
Self, direct manager, or admin
endDate?startDate?workspaceId?
create_time_off_requestwrites
Submit time off. Employees submit only for themselves; admins for anyone. Managers can't submit on behalf of reports.
Details
Scope
time-off:manage-requests or self:manage-requests
Who
Self or admin only — no manager path
Note
Validates the policy is active, rejects overlapping requests, and enforces the leave policy's maximum business days. Pass leavePolicyId for unpaid leave rather than PTO.
Server
self:manage-requests submits ONLY for the caller's own record; admins may submit for anyone. There is deliberately no manager-submits-for-report path (the employee submits their own). Validates policy active/effective, range overlap, and the leave policy's max business days before the scoped-service ownership check.
employeeRecordIdpaidTimeOffPolicyIdstartDateendDateleavePolicyId?notes?workspaceId?
cancel_time_off_requestwrites
Cancel a request — by the requester, their direct manager, or an admin.
Details
Scope
time-off:manage-requests or self:manage-requests
Who
Self, direct manager, or admin
Server
Ownership (self / manager-of-requester / admin) is enforced inside the scoped service, so the wider scope gate cannot cancel another employee's request.
timeOffRequestId
approve_requestwrites
Approve or reject a time-off request.
Details
Scope
time-off:manage-requests
Who
Direct manager or admin
status
APPROVEDREJECTED
timeOffRequestIdstatus
list_company_holidays
Company holidays with concrete dates resolved for a year, floating holidays included.
workspaceId?year?

Invoices

The contractor and vendor invoice lifecycle.

Scopesemployee:manage-invoicespayroll:manage-invoicesself:manage-invoices

Tool
Description
Parameters
create_invoicewrites
Submit a contractor invoice from fields you already have, with a URL to the stored document.
Details
Scope
self:manage-invoices or employee:manage-invoices or payroll:manage-invoices
Who
Self, direct manager, or admin
Server
self:manage-invoices submits for the caller's own record; employee:/payroll: scopes submit for others. employee scope does not separately re-check direct-manager here.
employeeRecordIdemployeeInvoiceNumbersubmissionDatedueDateamountcloudURLnote?workspaceId?
submit_invoicewrites
Upload an invoice file and let AI extract the fields. Fails if number, dates or amount can't be extracted. Trial employees auto-approve.
Details
Scope
self:manage-invoices or employee:manage-invoices
Who
Self, or a bypass scope — no manager path
Note
Provide either attachmentId (a file attached in chat) or fileName + fileBase64 — 50 MB max. Authorization runs before upload and extraction.
Server
self:manage-invoices submits for the caller's own record only; employee:manage-invoices is the bypass for submitting on any eligible employee (no direct-manager re-check, and the admin flag is not consulted — parity with invoices.routes.ts userCanSubmitInvoiceForEmployee). Authorization runs BEFORE upload/extraction. Trial self-submits are auto-approved.
employeeRecordIdattachmentId?fileBase64?fileName?note?workspaceId?
list_invoices
A contractor's or vendor's invoices, newest first.
Details
Scope
self:manage-invoices or employee:manage-invoices or payroll:manage-invoices
Who
Self, or a bypass scope — no manager path
status
SUBMITTEDAPPROVEDREJECTEDPAID
Server
self:manage-invoices reads the caller's own invoices only; employee:manage-invoices or payroll:manage-invoices is the bypass for reading any eligible employee's invoices (no direct-manager re-check, and the admin flag is not consulted — parity with invoices.routes.ts userCanManageInvoiceForEmployee).
employeeRecordIdstatus?workspaceId?
approve_invoicewrites
Approve a submitted invoice.
Details
Scope
employee:manage-invoices or payroll:manage-invoices
Who
Direct manager or admin
Note
payroll:manage-invoices approves any invoice; employee:manage-invoices only your direct reports'.
Server
payroll:manage-invoices approves any invoice; employee:manage-invoices approves only invoices for the actor's direct reports.
invoiceId
reject_invoicewrites
Reject a submitted or approved invoice that isn't on a payroll.
Details
Scope
employee:manage-invoices or payroll:manage-invoices
Who
Direct manager or admin
Server
Same scope/relationship rule as approve_invoice.
invoiceId
unapprove_invoicewrites
Move an approved invoice back to SUBMITTED, if it isn't on a payroll.
Details
Scope
employee:manage-invoices or payroll:manage-invoices
Who
Direct manager or admin
Server
Same scope/relationship rule as approve_invoice.
invoiceId
cancel_invoicewrites
Hard-delete a submitted or approved invoice that isn't on a payroll.
Details
Scope
self:manage-invoices or employee:manage-invoices or payroll:manage-invoices
Who
Self, direct manager, or admin
Server
self:manage-invoices cancels the caller's own; employee:/payroll: scopes cancel others'.
invoiceId

Terminations

Termination records, state final-pay timing rules, and the termination itself.

Scopesemployee:terminate

Tool
Description
Parameters
list_terminations
Every termination in the workspace, in any state.
Details
Scope
employee:terminate
Who
Scope only — any holder, every record
workspaceId?
get_termination_payment_date_info
Final-pay constraints under state rules: latest pay date, direct-deposit lead time, and the rule in plain English.
Details
Scope
employee:terminate
Who
Scope only — any holder, every record
type
VOLUNTARYINVOLUNTARY
Note
Call this before terminate_employee to pick a valid paymentDate. type defaults to INVOLUNTARY.
Server
No per-record relationship check (unlike terminate_employee): any workspace member holding employee:terminate may read pay-date constraints for any employee. Returns rule data only (latest pay date, direct-deposit lead time, state rule explanation) — no compensation values.
employeeRecordIdterminationDatetype?
terminate_employeewrites
Terminate with UI-equivalent validation. Optionally creates the final-pay off-cycle (on by default).
Details
Scope
employee:terminate
Who
Direct manager or admin
type
VOLUNTARYINVOLUNTARY
paymentMethod
DIRECT_DEPOSITCHECKBANK_TRANSFER
Note
severanceAmount applies to INVOLUNTARY only. ptoPayoutHours: 8 hours per accrued PTO day. Rejected for an already-terminated employee, a date outside state rules, a missed direct-deposit lead time, or a holiday.
Server
UI-equivalent validation (state pay-date rules, direct-deposit lead time, holidays, existing termination). Optionally creates an off-cycle final-pay payroll (createOffcyclePayroll, default true).
employeeRecordIdterminationDatepaymentDatetypepaymentMethodnote?severanceAmount?payOutPto?ptoPayoutAmount?ptoPayoutHours?createOffcyclePayroll?workspaceId?

Approvals

The generic approval-task surface.

Scopestime-off:manage-requests

Tool
Description
Parameters
get_approval_state
An approval task's status: PENDING, ACCEPTED, REJECTED or CANCELLED.
Details
Scope
None required
Who
Self, direct manager, or admin
Server
No scope required, but the relationship gate still applies.
approvalId
cancel_approvalwrites
Cancel an approval task that isn't already in a terminal state.
Details
Scope
time-off:manage-requests
Who
Direct manager or admin
approvalId
update_approvalwrites
Change a task's name, description and/or status. Terminal tasks can't be updated.
Details
Scope
time-off:manage-requests
Who
Direct manager or admin
status
ACCEPTEDREJECTEDCANCELLED
approvalIdname?description?status?

Organization

Departments and the reporting hierarchy.

Scopesemployee:manage-data

Tool
Description
Parameters
list_departments
Departments, from the system-department dropdown choices.
workspaceId?
list_org_chart
A nested tree of active employees by manager. Employees with no visible manager are root nodes.
Details
Scope
employee:manage-data
Who
Scope only — any holder, every record
Note
Rows aren't relationship-filtered, but custom-property columns you can't see are blanked.
Server
Rows are not relationship-filtered, but custom-property columns the actor cannot see are blanked per the actor's visibility (admins see all columns).
workspaceId?

Custom Properties

Workspace custom property definitions, and app-namespaced properties.

Scopesadmin:manage-customizationemployee:manage-data

Tool
Description
Parameters
list_custom_properties
Property definitions — not values. Excludes app-namespaced and internal properties.
Details
Scope
employee:manage-data
Who
Scope only — any holder, every record
Server
Returns definitions, not record values. App-prefixed and internal definitions are excluded.
workspaceId?
list_app_properties
Properties belonging to one app integration, by appId prefix.
Details
Scope
employee:manage-data
Who
Scope only — any holder, every record
appIdworkspaceId?
create_app_propertywrites
A new app-namespaced property; the label is prefixed with {appId}-. Returns null if it already exists.
Details
Scope
admin:manage-customization
Who
Admins only
type
SHORTLONGRICHPHONENUMBERCURRENCYEMAILDATECHECKBOX_SINGLECHECKBOX_MULTIPLEDROPDOWNRADIOFILEADDRESS
appIdlabeldisplaytypedescription?group?required?settings?workspaceId?

Artifacts — Employee Data Storage

App-scoped records attached to an employee. A non-admin caller can only write to an appId namespace that's already registered.

Scopesadmin:manage-artifactsemployee:manage-data

Tool
Description
Parameters
create_artifactwrites
Attach data to an employee — notes, checklists, reviews, equipment, anything — grouped under your appId.
Details
Scope
employee:manage-data
Who
Direct manager or admin
type
TEXTMARKDOWNIMAGEFILEJSONCARDURL
Note
Auto-registration was removed on 2026-07-14: writing to an unregistered appId needs admin:manage-artifacts, or call register_artifact_app first. See the artifact data shapes below.
Server
Auto-registration was removed (2026-07-14): writing to an UNREGISTERED appId namespace is refused unless the caller holds admin:manage-artifacts. Register the namespace first with register_artifact_app (or, over REST, POST /api/artifact-apps/create with the manage:artifacts OAuth scope). Writing to an already-registered namespace needs only employee:manage-data + the relationship gate.
employeeRecordIdappIdtypeappName?content?employeeVisible?fileName?payload?url?
update_artifactwrites
Change an artifact. Fields you pass merge with the existing data.
Details
Scope
employee:manage-data
Who
Direct manager or admin
artifactIdcontent?fileName?payload?url?
get_artifact
One artifact by id.
Details
Scope
employee:manage-data
Who
Self, direct manager, or admin
artifactId
list_artifacts
An employee's artifacts. Listing across all apps (no appId) needs admin:manage-artifacts.
Details
Scope
employee:manage-data
Who
Self, direct manager, or admin
employeeRecordIdappId?
delete_artifactwrites
Remove an artifact.
Details
Scope
employee:manage-data
Who
Direct manager or admin
artifactId
register_artifact_appwrites
Register an appId namespace — the required setup step before non-admins can write artifacts under it.
Details
Scope
admin:manage-artifacts
Who
Admins only
Note
MCP-registered apps are auto-approved. Returns the existing app if the appId is already registered.
Server
This is the REQUIRED setup step before non-admin callers can create_artifact under a new appId — auto-registration no longer exists. MCP-registered apps are auto-approved. REST equivalent: POST /api/artifact-apps/create (OAuth scope manage:artifacts → internal admin:manage-artifacts).
appIdnamedescriptionfaviconUrl?
list_artifact_apps
Every app registered to store data on employee records.
Details
Scope
admin:manage-artifacts
Who
Any workspace member
none

Automation — Scheduled Tasks

Your own recurring tasks, on a 5-field cron and an IANA timezone. Every tool acts only on the caller's tasks.

Scopesagents:automate

Tool
Description
Parameters
list_tasks
Your scheduled tasks: prompt, cron, timezone, destination and enabled status.
Details
Scope
agents:automate
Who
Any workspace member
none
schedule_taskwrites
Schedule a recurring agent run as yourself; the output posts to your destination.
Details
Scope
agents:automate
Who
Any workspace member
destination.type
dmchannelemployee
Note
cron is 5-field — "0 9 * * 1" is every Monday at 09:00. timezone e.g. America/New_York. destination: omit for a DM to you; {"type":"channel","channelId":"C..."} for a Slack channel; or {"type":"employee","employeeRecordId":"..."} to DM a specific employee.
Server
Owner is always stamped as the requesting actor — the tool cannot schedule on behalf of anyone else.
promptcrontimezonedestination?
run_taskwrites
Run one of your scheduled tasks now.
Details
Scope
agents:automate
Who
Any workspace member
id
pause_taskwrites
Pause a scheduled task until unpaused.
Details
Scope
agents:automate
Who
Any workspace member
id
unpause_taskwrites
Re-enable a paused task.
Details
Scope
agents:automate
Who
Any workspace member
id
cancel_taskwrites
Cancel and permanently delete a scheduled task.
Details
Scope
agents:automate
Who
Any workspace member
id

Automation — Event Subscriptions

Your own event subscriptions: when a Winslow event fires, the agent runs your prompt and delivers the result.

Scopesagents:automate

Tool
Description
Parameters
list_subscriptions
Your subscriptions: objectType, eventKey, prompt, destination and enabled status.
Details
Scope
agents:automate
Who
Any workspace member
none
subscribe_eventwrites
Run a prompt whenever a Winslow event fires — by business moment, by (objectType, eventKey), or "*".
Details
Scope
agents:automate
Who
Any workspace member
eventKey (business moments)
employee.compensation_changedemployee.manager_changedemployee.department_changedemployee.terminated
objectType
employee-recordemployee-documentinvoiceterminationtime-off-requestbenefit-electionlife-event-requestpayroll-runpaystubcompanyopen-enrollmentplanplan-selectiondependentpto-adjustmentpayroll-adjustmentpayroll-deductionpayroll-reimbursementemployee-milestonepto-policyleave-policycompany-holidaytax-document
destination.type
dmchannelemployee
Note
objectType is optional when eventKey is a business moment. fieldFilters limits generic update events to changes in the named fields. destination: omit for a DM to you; {"type":"channel","channelId":"C..."} for a Slack channel; or {"type":"employee","employeeRecordId":"..."} to DM a specific employee. The full per-objectType event-key catalog is returned by get_api_docs.
Server
Owner is always stamped as the requesting actor — the tool cannot subscribe on behalf of anyone else.
eventKeypromptobjectType?fieldFilters?destination?
update_subscriptionwrites
Change a subscription's prompt, destination, objectType, eventKey or fieldFilters.
Details
Scope
agents:automate
Who
Any workspace member
Note
Pass fieldFilters: [] to clear them.
Server
Owner guard: if the subscription's ownerUserId or workspaceId doesn't match the actor the error is indistinguishable from not-found (no data leak).
iddestination?eventKey?fieldFilters?objectType?prompt?
enable_subscriptionwrites
Re-enable a paused subscription.
Details
Scope
agents:automate
Who
Any workspace member
id
pause_subscriptionwrites
Pause a subscription until re-enabled.
Details
Scope
agents:automate
Who
Any workspace member
id
cancel_subscriptionwrites
Permanently delete a subscription.
Details
Scope
agents:automate
Who
Any workspace member
id

Automation — Workspace Skills

Reusable HR and process playbooks shared with everyone in the workspace.

Scopesadmin:manage-customization

Tool
Description
Parameters
list_skills
Every workspace skill: name, description, creator, created date.
Details
Scope
admin:manage-customization
Who
Admins only
none
save_skillwrites
Create a workspace-wide skill — a markdown playbook the agent follows.
Details
Scope
admin:manage-customization
Who
Admins only
Note
name: 1–64 lowercase letters, numbers or hyphens, unique in the workspace. description ≤1024 chars.
namedescriptionbody
update_skillwrites
Replace a skill's description and body. Creates a new version the agent picks up next session.
Details
Scope
admin:manage-customization
Who
Admins only
namedescriptionbody
cancel_skillwrites
Delete a skill and detach it from the agent.
Details
Scope
admin:manage-customization
Who
Admins only
name

Automation — Agent Sequences

Durable cross-session state and checklists for multi-step agent workflows.

Scopesagents:manage

Tool
Description
Parameters
list_open_sequences
Open (not completed or cancelled) sequences for a workflow key — what's in flight.
Details
Scope
agents:manage
Who
Admins only
key
upsert_sequencewrites
Create or fetch a durable sequence — e.g. an onboarding follow-up for a new hire.
Details
Scope
agents:manage
Who
Admins only
Note
Idempotent per (key, objectType, objectId): calling again returns the existing row.
Server
Owner is always stamped as the requesting actor. Idempotent per (key, objectType, objectId) 4-tuple.
keyanchorAt?objectId?objectType?
update_sequencewrites
Set a sequence's status and/or merge fields into its state to record progress.
Details
Scope
agents:manage
Who
Admins only
status
NEWAWAITINGNUDGEDESCALATEDCOMPLETEDCANCELLED
Server
Workspace-ownership guard: if the sequence's workspaceId doesn't match the actor the error is indistinguishable from not-found (no cross-workspace leak). Status must be one of NEW | AWAITING | NUDGED | ESCALATED | COMPLETED | CANCELLED.
idstate?status?

Automation — Slack

Slack destinations and agent-run follow-ups.

Scopesagents:automateagents:manage

Tool
Description
Parameters
resolve_slack_channel
Turn a channel name into a channel id for an automation destination. The bot must be a member to post.
Details
Scope
agents:automate
Who
Any workspace member
Server
Read-only Slack channel lookup; owner/actor scoped to their workspace's Slack bot.
query
send_slack_dmwrites
DM an employee, or their manager. Returns { delivered: false } when no Slack identity resolves.
Details
Scope
agents:manage
Who
Admins only
recipient
employeemanager
Server
Sends a DM to the target employee or their manager. Returns { delivered: false } when no Slack identity can be resolved (no error thrown).
employeeRecordIdmessagerecipient?
check_employee_reply
Whether an employee has sent any Slack DM since a given time — to decide if a follow-up is needed.
Details
Scope
agents:manage
Who
Admins only
Server
Returns { replied, lastMessageAt } — replied is false when no Slack identity can be resolved.
employeeRecordIdsinceISO

AI & Knowledge Base

RAG over workspace HR policy documents, and natural-language reporting over employee data.

Scopesemployee:manage-data

Tool
Description
Parameters
ask_policy_question
Ask your uploaded handbooks and policies a question. Returns a markdown answer and its sources.
Details
Scope
None required
Who
Any workspace member
Note
No per-employee record data flows through this tool, and no other workspace's knowledge base is reachable.
Server
Per-employee record fields never flow through this tool (employeeData is null in the pipeline). Cross-workspace KB content is never reachable.
question
ask_reporting_question
Ask a reporting question about employee data. Returns an explanation and a table.
Details
Scope
employee:manage-data
Who
Self, direct manager, or admin
Note
Actor scoping happens at the data-load layer, so the model can't report a field you couldn't read directly.
Server
The model can never report a field the caller couldn't read directly — actor scoping is applied at the data-load layer, not in the prompt.
question

OAuth App Management

Register and maintain "Login with Winslow" OAuth apps for this workspace.

Scopesadmin:manage-customization

Tool
Description
Parameters
register_oauth_appwrites
All-in-one OAuth setup: registers the app and returns credentials, env vars, the authorize URL and ready-to-paste code.
Details
Scope
admin:manage-customization
Who
Admins only
framework
reactnextexpressgeneric
Note
clientSecret is shown once and never retrievable again. Use this — not POST /oauth/register, which is only for MCP clients — when building an app that signs users in with Winslow. Derive the redirect URI from the runtime origin, never a build-time URL.
nameredirectUrisscopes?description?framework?
list_oauth_apps
OAuth apps in this workspace. Client secrets are never returned.
Details
Scope
admin:manage-customization
Who
Admins only
none
update_oauth_appwrites
Change an app's redirect URIs, name, description, scopes or icon without re-registering.
Details
Scope
admin:manage-customization
Who
Admins only
Note
Use addRedirectUris / removeRedirectUris to edit safely, or redirectUris to replace the whole set — not both. A loopback wildcard like http://localhost:*/callback matches any dev port.
clientIdaddRedirectUris?description?iconUrl?name?redirectUris?removeRedirectUris?scopes?
delete_oauth_appwrites
Deactivate an app. Existing tokens work until they expire (30 days); no new ones are issued.
Details
Scope
admin:manage-customization
Who
Admins only
clientId

Feedback

Report bugs and suggest improvements to the MCP API.

ScopesNone — any workspace member

Tool
Description
Parameters
report_bugwrites
Report something that errored, misbehaved or returned the wrong result.
titledescription?toolName?agentContext?
suggest_improvementwrites
Suggest an improvement or a new capability.
titledescription?toolName?agentContext?

Documentation

Self-describing API documentation.

ScopesNone — any workspace member

Tool
Description
Parameters
get_api_docs
The Winslow API guide: OAuth, REST, MCP tools, auth and a quick start. section=matrix returns the per-tool reference as JSON.
Details
Scope
None required
Who
Any workspace member
section
overviewoauthauthrestmcpquickstartauthzmatrixall
Note
section=matrix is the machine-readable source this page is checked against.
section?
Not in the MCP

REST or UI only, on purpose.

There is no MCP tool for these. Use the admin UI or the REST API.

  • SPD and plan-document attachment upload
  • Plan document ingest
  • Census and election CSV export
  • Broker import (carrier file reconciliation)
  • Broker create and update — brokers are read-only via list_brokers
  • QLE elections — never written by any tool; they stay employee-attested
Guides

The parts integrators actually read.

Benefits onboarding, end to end

  1. Configuration — get_benefits_configuration (created on first read), then update_benefits_configuration to set hasFullCensus if it applies.
  2. Plans — create_benefit_plan for each medical, dental and vision plan (PENDING). Move each to VERIFIED with update_benefit_plan once carrier terms are confirmed.
  3. Offerings — create_plan_offering per plan (rates, coverage, employer contribution), or copy_plan_offerings_from_previous to roll a plan into a new period.
  4. Plan selection — create_plan_selection (DRAFT) → open_plan_selection → close_plan_selection → finalize_plan_selection with the chosen selectedPlanIds.
  5. Coverage period — create_coverage_period → activate_open_enrollment, which creates PENDING elections for every eligible employee × offered plan type.
  6. Tracking — get_enrollment_tracking through the window; send_enrollment_reminders for anyone who hasn't submitted.
  7. Elections — employees (or an admin with benefits:manage-oe) call update_employee_election / waive_employee_election per plan type, then submit_employee_enrollment with a signature. Admins reconcile with list_period_elections, admin_update_election and set_election_status.
  8. Close and finalize — close_open_enrollment, then finalize_open_enrollment with acknowledged: true. Call it once first to preview any verification blockers.

QLEs run alongside, any time: preview_life_event_requirements → file_life_event_request → admin review → update_life_event_request_status. APPROVED opens a 7-day QLE window and drafts elections; the employee completes it with get_qle_enrollment and the same election tools.

Payroll response shape

list_payrolls returns summaries. get_payroll returns a curated PayrollView keyed by Winslow employeeRecordIds — no Check ids — with totals, per-employee pay, contractors, and a freshness block. Monetary values are strings for precision (e.g. "15000.00").

{
  "payrollId": "payroll-id",
  "status": "paid",
  "type": "regular",
  "periodStart": "2024-02-01",
  "periodEnd": "2024-02-14",
  "payday": "2024-02-16",
  "approvalDeadline": "2024-02-15T18:00:00Z"
}

Payroll adjustment templates

recurrenceType: ONE_TIME (needs oneTimeOnPayroll ≥ 1), MONTHLY, FIRST_HALF (first payroll of the month), SECOND_HALF. amountType: FIXED_ALL, ASSIGNED_PER_PERSON, CUSTOM_REQUIRED. targetType: EMPLOYEE_TYPE, EMPLOYEE_LIST, DEPARTMENT.

Example — a $150 gym supplement on the first payroll of each month for US full-time:

recurrenceType: "FIRST_HALF",  amountType: "FIXED_ALL",  fixedAmount: 150,
targetType: "EMPLOYEE_TYPE",   targetEmployeeTypes: ["US_FULL_TIME"],
checkPayrollItemType: "bonus", active: true

Benefit adjustment rules

  • ONGOING must not include checkPayrollId. ONE_TIME requires it, and the employee must be on that payroll.
  • Amounts are dollars, zero or greater; a ONE_TIME employeeAmount must be greater than zero.
  • One ONGOING per employee + election; one ONE_TIME per employee + election + payroll.

Artifact types and data shape

Type
Required
Example data
TEXT
content
{ "content": "Plain text note" }
MARKDOWN
content
{ "content": "# Heading\nBody text" }
CARD
payload
{ "payload": { "title": "Card", "fields": [{ "label": "Status", "value": "Active" }] } }
JSON
payload
{ "payload": { "any": "json structure" } }
URL
url
{ "url": "https://example.com" }
IMAGE
url
{ "url": "https://example.com/photo.png" }
FILE
url
{ "url": "https://…/file.pdf", "fileName": "report.pdf" }
  • The payload sits at artifact.data.payload (CARD, JSON) or artifact.data.content (TEXT, MARKDOWN) — each artifact has its own data field.
  • MCP responses call the namespace appId. REST calls the same value applicationId (and accepts appId as an alias on requests). REST also wraps responses in { "data": … }.
  • fields[].type is an optional rendering hint — one of TEXT, MARKDOWN, IMAGE_URL, FILE_URL, URL, PROGRESS, CURRENCY, TABLE. Always uppercase; omit for plain text.

Two-step document upload

begin_employee_document_upload is the preferred path for PDF, DOCX, or anything over 256 KB. Step 1 returns a signed uploadUrl that expires in 15 minutes. Step 2 is a multipart POST of the raw file to that URL — one part named file, 100 MB max. The URL is already signed, so no MCP auth header and no x-client-token is needed. upload_employee_document (base64) is capped at 256 KB decoded.

Separate server

Winslow Onboarding.

Self-serve payroll onboarding for a company that isn't on Winslow yet. This is a different MCP server from the 185-tool one above — its endpoint and keys are not interchangeable with it.

Tool
Description
Parameters
start_onboarding
Begin self-serve payroll onboarding for a new company. Returns a sessionId and the full field checklist.
companyName
update_onboarding
Merge any subset of company, signatory, bank account and onboarder fields into an in-progress session.
Details

fields.businessType: sole_proprietorship, partnership, c_corporation, s_corporation, llc, government_entity. fields.firstPayrollDate (YYYY-MM-DD) is the end of the first semi-monthly period — a future 15th or last day of the month. Check sets the actual pay date; weekly and biweekly schedules are not accepted.

sessionIdfields
complete_onboarding
Validate everything, create the workspace, configure Check payroll, provision an admin and send the invite. Only once get_onboarding_status reports readyToComplete.
sessionId
get_onboarding_status
The collected (masked) data, the missing fields, and whether the session is ready to complete.
sessionId
Sample prompts

What it looks like in practice.

Real prompts you can drop into Claude or ChatGPT once your MCP is connected. The right-hand side shows the tools the model picks up to answer.

"Who's on PTO next week and is anyone managing more than 8 direct reports?"
→ list_time_off + list_org_chart + list_employees
"Pay everyone in the Boston office a $500 spot bonus on the next payroll."
→ list_employees (filter by office) → create_payroll_adjustment (per employee)
"Find Cooper's signed offer letter and check it's been countersigned."
→ find_employee_documents + get_employee_document_content + set_employee_document_validation
"Build me a dashboard of comp by department for engineering."
→ ask_reporting_question, or list_managed_employees + list_departments (list_employees is PUBLIC fields only — no comp)
"What does our parental leave policy say for employees in New York?"
→ ask_policy_question (answers from your uploaded policies — no per-employee record data)

Build something in an afternoon.

Point your favorite agent at the MCP and build the People-team tool you've been waiting on procurement for. We'll show you how if you want help — or get out of your way if you don't.

I hate demos