Benefits

A benefit deduction is an amount withheld from an employee's pay for an elected benefit — health insurance, retirement contributions, a flexible spending account, and similar. Unlike a one-off deduction, a benefit deduction is set up through enrollment: you create a definition for the benefit (its type, its tax treatment, how much comes out of pay and how much the employer contributes), and that definition governs the withholding going forward.

Most benefit deductions are pre-tax — subtracted from gross pay before federal/state income tax and FICA are calculated, which is what actually lowers the employee's taxable wages. Some are post-tax instead. Examples of each:

  • Pre-tax: health/dental/vision premiums, HSA contributions, FSA (medical and dependent care), traditional 401(k)/403(b).
  • Post-tax: Roth 401(k) (taxed going in, not coming out), and other after-tax elections.

Every benefit deduction carries a taxability value (see below) that tells Worklio which of these treatments applies, since that determines which tax calculations the deduction is netted out of before they run.

There are two ways to create a benefit deduction, at two different scopes:

  • Company benefit templates — a reusable definition at the company level that employees can be enrolled into.
  • Employee-specific benefit deductions — enroll a specific employee, either against an existing company benefit template or as a one-off deduction for just that employee.

Both are covered below.

Auth

Requires a bearer access token (see How to Get API Access).

Company benefit templates

Creates a reusable benefit definition at the company level.

Endpoint

POST https://api.worklio.com/wep/companies/{CLIENT_ID}/benefittemplates

CLIENT_ID is the company identifier returned as id when you create the company.

Request fields

FieldTypeRequiredDescription
namestringYesLabel for this benefit, e.g. "Vision". Free text — it isn't validated against deductionType.
startDatestring (ISO date)YesDate the benefit becomes effective.
deductionTypeintegerYesThe kind of benefit. See Deduction Type values below.
taxabilityintegerYesTax treatment of the deduction. See Taxability values below.
employeeDeductionobjectYesHow much is withheld from the employee's pay. See "Deduction/contribution object" below.
employerContributionobjectYesHow much the employer contributes toward this benefit (not withheld from pay). Same shape as employeeDeduction.

Deduction/contribution object (employeeDeduction and employerContribution):

FieldTypeRequiredDescription
typeintegerYes1 = fixed amount — amount is a flat dollar amount. 2 = percentage — amount is a percentage. (Same convention as allocatedBy on pay allocations.)
amountnumberYesThe dollar amount or percentage, depending on type.

Deduction Type values:

ValueNameMeaning
1Insurance_MedicalMedical insurance
2Insurance_DentalDental insurance
3Insurance_VisionVision insurance
11Suppl_STDShort-term disability
12Suppl_LTDLong-term disability
13Suppl_GTLGroup term life
14Suppl_VoluntaryLifeVoluntary life
19Suppl_VoluntaryBenefitVoluntary benefit
21Spend_FSAMedicalFSA — medical
22Spend_FSADependentCareFSA — dependent care
23Spend_FSALimitedFSA — limited
24Spend_HSAHSA — health savings account
25Spend_CommuterCommuter
41Retire_401k401(k)
42Retire_403b403(b)
43Retire_408k408(k)
44Retire_457457
45Retire_501c501(c)
51Retire_SimpleIRASimple IRA

Taxability values (taxability):

ValueNameMeaning
1PretaxWithheld before federal/state income tax and FICA are calculated
2AftertaxWithheld after tax calculations
3SCorpS-Corp-specific tax treatment
4DomesticPartnerDomestic partner benefit tax treatment
5RothRoth tax treatment (taxed going in, not coming out)

Example request

require("dotenv").config();

const TOKEN = process.env.API_KEY;
const CLIENT_ID = process.env.CLIENT_ID;
const url = `https://api.worklio.com/wep/companies/${CLIENT_ID}/benefittemplates`;

const payload = {
  name: "Vision",
  startDate: "2026-09-15T00:00:00.000Z",
  deductionType: 3, // Insurance_Vision
  taxability: 1, // Pretax
  employeeDeduction: {
    type: 1, // fixed amount
    amount: 50
  },
  employerContribution: {
    type: 1, // fixed amount
    amount: 50
  }
};

async function createBenefitTemplate() {
  const response = await fetch(url, {
    method: "POST",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "content-type": "application/json",
      "x-api-version": "2.0"
    },
    body: JSON.stringify(payload)
  });

  console.log(response.status);
  console.log(await response.text());
}

createBenefitTemplate();
curl -s -X POST "https://api.worklio.com/wep/companies/$CLIENT_ID/benefittemplates" \
  -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" \
  -d '{
    "name": "Vision",
    "startDate": "2026-09-15T00:00:00.000Z",
    "deductionType": 3,
    "taxability": 1,
    "employeeDeduction": { "type": 1, "amount": 50 },
    "employerContribution": { "type": 1, "amount": 50 }
  }' | jq .

Example response

{
  "id": 234,
  "name": "Vision",
  "startDate": "2026-09-15",
  "deductionType": 3,
  "taxability": 1,
  "highEarnerInPriorYear": false,
  "employeeDeduction": {
    "type": 1,
    "amount": 50
  },
  "employerContribution": {
    "type": 1,
    "amount": 50
  }
}
{
  "status": 3,
  "code": "DataValidationError",
  "errorCode": "",
  "message": "One or more validation errors occurred.\r\n$.deductionType: [The JSON value could not be converted to System.Nullable`1[Worklio.ApiModels.API.Enums.Benefits.DeductionType_v10]. Path: $.deductionType | LineNumber: 0 | BytePositionInLine: 75.]",
  "stackTrace": "",
  "pagination": {
    "pageNo": 0,
    "pageSize": 0,
    "totalRecords": 0,
    "totalPages": 0,
    "dataToken": ""
  },
  "validationErrors": {
    "$.deductionType": [["The JSON value could not be converted to System.Nullable`1[Worklio.ApiModels.API.Enums.Benefits.DeductionType_v10]. Path", "$.deductionType | LineNumber: 0 | BytePositionInLine: 75."]]
  }
}

id is the benefit template's unique identifier, save it if you plan to enroll employees against this template (see below). highEarnerInPriorYear flags whether the employee was a high earner in the prior tax year — that status affects eligibility, cost, and contribution limits for healthcare, retirement, and other benefit types.

Employee-specific benefit deductions

Enrolls a single employee in a benefit. There are two ways to call this endpoint:

  • Without templateId — creates a one-off benefit deduction for just this employee. employeeDeduction and employerContribution aren't accepted in the request body, so the created deduction comes back with both amounts set to 0.
  • With templateId — enrolls the employee against an existing company benefit template, and the created deduction inherits that template's employeeDeduction and employerContribution amounts.

Endpoint

POST https://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/deductions/benefit

CLIENT_ID is the company identifier returned as id when you create the company. EMPLOYEE_ID is the employee identifier returned as id when you create the employee.

Query parameters

ParameterTypeRequiredDescription
templateIdintegerNoThe id of an existing company benefit template (returned when you create one). When set, the created deduction inherits that template's employeeDeduction and employerContribution amounts instead of defaulting to 0.

Request fields

FieldTypeRequiredDescription
namestringYesLabel for this benefit. Required whether or not templateId is set.
startDatestring (ISO date)YesDate the benefit becomes effective.
deductionTypeintegerYesThe kind of benefit. See Deduction Type values above.
taxabilityintegerYesTax treatment of the deduction. See Taxability values above.

employeeDeduction and employerContribution are never sent in the request body for this endpoint — the amounts either default to 0 or come from the referenced template, per templateId above.

Example request — one-off (no template)

require("dotenv").config();

const TOKEN = process.env.API_KEY;
const CLIENT_ID = process.env.CLIENT_ID;
const EMPLOYEE_ID = process.env.EMPLOYEE_ID;
const url = `https://api.worklio.com/wep/companies/${CLIENT_ID}/employees/${EMPLOYEE_ID}/deductions/benefit`;

const payload = {
  name: "Vision",
  startDate: "2026-09-15T00:00:00.000Z",
  deductionType: 3, // Insurance_Vision
  taxability: 1 // Pretax
};

async function addEmployeeBenefit() {
  const response = await fetch(url, {
    method: "POST",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "content-type": "application/json",
      "x-api-version": "2.0"
    },
    body: JSON.stringify(payload)
  });

  console.log(response.status);
  console.log(await response.text());
}

addEmployeeBenefit();
curl -s -X POST "https://api.worklio.com/wep/companies/$CLIENT_ID/employees/$EMPLOYEE_ID/deductions/benefit" \
  -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" \
  -d '{
    "name": "Vision",
    "startDate": "2026-09-15T00:00:00.000Z",
    "deductionType": 3,
    "taxability": 1
  }' | jq .

Example response

{
  "id": 567,
  "name": "Vision",
  "startDate": "2026-09-15",
  "deductionType": 3,
  "deductionCode": "CNVIS-PT",
  "taxability": 1,
  "highEarnerInPriorYear": false,
  "employeeDeduction": {
    "type": 1,
    "amount": 0
  },
  "employerContribution": {
    "type": 1,
    "amount": 0
  }
}

Example request — enrolling against an existing template

require("dotenv").config();

const TOKEN = process.env.API_KEY;
const CLIENT_ID = process.env.CLIENT_ID;
const EMPLOYEE_ID = process.env.EMPLOYEE_ID;
const TEMPLATE_ID = process.env.TEMPLATE_ID; // the `id` from creating the company benefit template
const url = `https://api.worklio.com/wep/companies/${CLIENT_ID}/employees/${EMPLOYEE_ID}/deductions/benefit?templateId=${TEMPLATE_ID}`;

const payload = {
  name: "Vision",
  startDate: "2026-09-15T00:00:00.000Z",
  deductionType: 3, // Insurance_Vision
  taxability: 1 // Pretax
};

async function addEmployeeBenefitFromTemplate() {
  const response = await fetch(url, {
    method: "POST",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "content-type": "application/json",
      "x-api-version": "2.0"
    },
    body: JSON.stringify(payload)
  });

  console.log(response.status);
  console.log(await response.text());
}

addEmployeeBenefitFromTemplate();
curl -s -X POST "https://api.worklio.com/wep/companies/$CLIENT_ID/employees/$EMPLOYEE_ID/deductions/benefit?templateId=$TEMPLATE_ID" \
  -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" \
  -d '{
    "name": "Vision",
    "startDate": "2026-09-15T00:00:00.000Z",
    "deductionType": 3,
    "taxability": 1
  }' | jq .

Example response

{
  "id": 574,
  "name": "Vision",
  "startDate": "2026-09-15",
  "deductionType": 3,
  "deductionCode": "CNVIS-PT",
  "taxability": 1,
  "highEarnerInPriorYear": false,
  "employeeDeduction": {
    "type": 1,
    "amount": 50.0000
  },
  "employerContribution": {
    "type": 1,
    "amount": 50.0000
  }
}
{
  "status": 0,
  "code": "404",
  "errorCode": null,
  "message": "9/16/2026 - 9:01:02 AM : TemplateId #200 does not exist for this CompanyId #1031.",
  "stackTrace": "",
  "pagination": {
    "pageNo": 0,
    "pageSize": 0,
    "totalRecords": 0,
    "totalPages": 0,
    "dataToken": ""
  },
  "validationErrors": null
}

id is this employee-level benefit deduction's unique identifier it is distinct from templateId, which stays the company template's identifier. deductionCode is a system-generated code combining an abbreviation for the benefit type and its tax treatment. In this example, VIS (vision) and PT (pretax).



Did this page help you?