Collecting Employee Information From Employers

Employees generally provide payroll-related information, such as their personal information or Social Security Number, themselves. There are cases in which an employer is required to provide this information on an employee's behalf. For example, in some states, an employer might be required to report if an employee is a corporate officer or a family member of the owner. Check knows when these employee attributes must be collected from the employer and surfaces them through our API, Console, and Onboard.

This guide describes how to collect this information from employers using the Check API.

Retrieving and updating company-defined attributes

First, use the /employees/<employee_id>/company_defined_attributes endpoint to access the list of employee attributes:

curl -X GET \
 'https://sandbox.checkhq.com/employees/<EMPLOYEE_ID>/company_defined_attributes' \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Bearer <API_KEY>'

If Check determines that the employer must specify that the employee is a corporate officer, the API would respond with the following:

{
   "company_defined_attributes": [
       {
           "name": "corporate_officer",
           "value": null,
           "type": "boolean",
           "label": "Corporate officer status",
           "description": "This employee is an owner or corporate officer of the business",
           "options": [
               {"label": "Yes", "value": "true"},
               {"label": "No", "value": "false"}
           ],
           "effective_start": null,
           "effective_start_required": false,
           "default_value": "false"
       }
   ]
}

The response contains a list of company_defined_attributes that must be collected, each containing the following fields:

  • name: (string) A unique identifier for the attribute.
  • value: (string, nullable) The assigned value for the attribute.
  • type: (string) One of string, number, currency, percent, boolean, or select, which specifies the type of the value.
  • options: (list, nullable) Optional list of selected options. Each option has human-readable label and value properties. Only populated when the attribute is of type select or boolean.
  • label: (string, nullable) A human-readable label that can be shown when rendering a form input.
  • description: (string, nullable) An optional description that can be used to display additional context when rendering a form input.
  • effective_start: (string, nullable) The effective start date of the assigned value in YYYY-MM-DD format.
  • effective_start_required: (boolean) Whether or not the company-defined attribute value must be submitted with an explicit effective date.
  • default_value: (string, nullable) The default value used for the attribute for informational purposes. The default_value for an attribute with a non-empty options list will always correspond to the value of one of those options. Note: The API does not automatically populate the attribute with this value.

Check provides the label and description fields to facilitate the creation of form inputs in your application. For example, you may want to collect this information by showing an extra step to the employer during the employee creation flow.

To set values for the desired attributes, send a PATCH request to the same endpoint with a list of name,value and optionally effective_start objects. In the case that no effective_start is defined, if the attribute has not yet been initialized it will be set to 1900-01-01, otherwise by default it will be set to the current date:

curl -X PATCH https://sandbox.checkhq.com/employees/<EMPLOYEE_ID>/company_defined_attributes -d '{
   "company_defined_attributes": [
       {"name": "corporate_officer", "value": "true", "effective_start": "2022-07-14"}
   ]
}

Onboard status

The state of an employee’s company-defined attribute will affect their onboard status. Depending on the attribute, if a value is not set, the employee’s onboard_status could either be in the blocking or needs_attention state. If the employee’s status is not completed, either set the values through the API as described above, or redirect the employer to Check Onboard to add this information for the affected employees.

To determine if an employee’s onboard_status is not in a completed state due to a company-defined attribute, inspect the employee’s onboard_object and look for company_defined_attributes in either the blocking or remaining steps.

IRS lock-in letters

The irs_lock_in_letter attribute records that the employer has an IRS lock-in letter (Letter 2800C) on file for the employee. It is a federal boolean attribute that defaults to "false", and it is returned for every employee. It is never required: leaving it unset doesn't add an onboarding step or change the employee's onboard status.

Here is how the attribute appears for an employee whose letter is on file:

{
   "company_defined_attributes": [
       {
           "name": "irs_lock_in_letter",
           "value": "true",
           "type": "boolean",
           "label": "Subject to IRS lock-in letter (2800C)",
           "description": "The IRS issued a lock-in letter (Letter 2800C) for this employee. While this is set, the employee's federal W-4 elections cannot be changed.",
           "options": [
               {"label": "Yes", "value": "true"},
               {"label": "No", "value": "false"}
           ],
           "effective_start": "2026-10-01",
           "effective_start_required": false,
           "default_value": "false"
       }
   ]
}

Set it to "true" or "false" with a PATCH request to the company_defined_attributes endpoint, as described above. The attribute is also returned by List an employee's tax parameters when you pass include_company_defined_attributes=true.

What the lock does

While the attribute's current value is "true", the employee's federal W-4 is frozen:

  • The nine federal W-4 elections can't be changed: w4_2020, filing_status, filing_status_2020_w4, total_allowances, dependents_amount, deductions, other_income, two_jobs, and additional_withholding.
  • Federal W-4 forms can't be previewed, submitted, or signed and submitted. This applies to every revision of the federal W-4.

The lock is federal only. State elections and state withholding forms keep working while an employee is locked. To lift the lock, set irs_lock_in_letter back to "false".

Showing the lock before a write

A locked employee's nine federal elections come back with editable: false from List an employee's tax parameters and Bulk get employee tax parameters, and in the responses of the two update endpoints below. Use it to show the elections as read-only before the employee or employer tries to change them.

The employee_federal_withholding_locked error

A request that would change a locked employee's federal election, or that previews or submits their federal W-4 form, returns a 400:

{
  "error": {
    "type": "employee_federal_withholding_locked",
    "message": "This employee is subject to an IRS lock-in letter. Their federal W-4 elections cannot be changed."
  }
}

This is a typed error that fails the whole request. It isn't a validation_error, so there is no input_errors array, and nothing in the request is written. In a bulk request, a refused change for one employee fails the request for every employee in it. A request that resubmits an election at its current value doesn't change anything, so it is not refused.

These routes can return it:

RouteEndpoint
PATCH /employee_tax_params/{employee_id}Update an employee's tax parameter
PATCH /employee_tax_params/settingsBulk update employee tax parameters
POST /employees/{employee}/forms/{form}/previewPreview an employee form, which renders the form as a PDF
POST /employees/{employee}/forms/{form}/submitSubmit an employee form
POST /employees/{employee}/forms/{form}/sign_and_submitSign and submit an employee form

Did this page help you?