Employee Documents

Use the employee documents endpoints to store files against an employee record, such as a signed Form W-4, a Form I-9 or a general HR document. You can upload a document, list an employee's documents, download one, and delete one.

All endpoints require a bearer access token (see How to Get API Access).

Endpoints overview

MethodNameEndpoint
GETList documentshttps://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/documents
POSTUpload a documenthttps://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/documents
GETDownload a documenthttps://api.worklio.com/wep/files/{fileToken}/info, then the returned downloadUri. See Downloading Documents.
DELETEDelete a documenthttps://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/documents/{DOCUMENT_ID}
ParameterTypeRequiredDescription
CLIENT_IDintegerYesThe company's id. Path parameter.
EMPLOYEE_IDintegerYesThe employee's id. Path parameter.
DOCUMENT_IDintegerYes (delete)The id of the document, as returned by Upload a document or List documents. Path parameter.

List employee documents

Returns the documents stored for an employee.

GET https://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/documents

This endpoint takes no request body.

Example request

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}/documents`;

async function listEmployeeDocuments() {
  const response = await fetch(url, {
    method: "GET",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "x-api-version": "2.0"
    }
  });

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

listEmployeeDocuments();
curl --request GET \
  --url "https://api.worklio.com/wep/companies/$CLIENT_ID/employees/$EMPLOYEE_ID/documents" \
  --header "accept: application/json" \
  --header "api-version: 2.0" \
  --header "authorization: Bearer $API_KEY" \
  --header "x-api-version: 2.0"

Example response

[
  {
    id: 142,
    caption: 'Form W-9',
    refId: 174,
    docType:6 ,
    fileToken: 'kx85lJPJkOvP_M7P0B8Hgcw8IhTEkVtHEyW_NcMocQ-NfvjcVC1jlCNyqSqwrhZ8s409qvsCgzI8xkSap_Ald8Dty4hLiEsmwQ4beVNqrkG_znA@@',
  "note": "Employee changed from W-2 to 1099 contractor.",
    clientSignatureRequired: false,
    employeeSignatureRequired: false
  }
]

Upload a document

Uploads a file and attaches it to the employee. The request body is multipart/form-data. The maximum file size is 25MB.

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

Request fields

FieldTypeRequiredDescription
filebinaryYesThe file to upload.
captionstringNoUser-facing caption for the document. Maximum 100 characters.
docTypeinteger (enum)NoThe document category. See Document type values.
notestringNoA note stored with the document.
employeeAccessinteger (enum)NoThe access the employee has to the document. See Employee access values.

Document type values

ValueNameMeaning
1GeneralGeneric document without a specialized tax-form workflow.
2W4IRS Form W-4 employee withholding document.
3I9Form I-9 employment eligibility verification document.
4Form8850IRS Form 8850 pre-screening notice and certification request.
5EnrollmentConfirmDocEnrollment confirmation document.
6W9IRS Form W-9 taxpayer identification request.

Employee access values

ValueNameMeaning
0NoneThe employee cannot access the document.
1ReadThe employee can read the document.
2WriteThe employee can read and modify the document.

Example request

This example uploads a PDF and gives the employee read access.

require("dotenv").config();
const fs = require("fs");
const path = require("path");

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}/documents`;

const fileName = "W9-2026.pdf";
const filePath = path.join(__dirname, fileName);

async function uploadEmployeeDocument() {
  const fileBuffer = fs.readFileSync(filePath);

  const form = new FormData();
  form.append("file", new Blob([fileBuffer], { type: "application/pdf" }), fileName);
  form.append("caption", "Form W-9");
  form.append("note", "Employee changed from W-2 to 1099 contractor.");
  form.append("docType", "6");
  form.append("employeeAccess", "1");

  const response = await fetch(url, {
    method: "POST",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "x-api-version": "2.0"
    },
    body: form
  });

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

uploadEmployeeDocument();
curl --request POST \
  --url "https://api.worklio.com/wep/companies/$CLIENT_ID/employees/$EMPLOYEE_ID/documents" \
  --header "accept: application/json" \
  --header "api-version: 2.0" \
  --header "authorization: Bearer $API_KEY" \
  --header "x-api-version: 2.0" \
  --form "[email protected];type=application/pdf" \
  --form "caption=Form W-9" \
  --form "note=Employee changed from W-2 to 1099 contractor." \
  --form "docType=6" \
  --form "employeeAccess=1"

Do not set the content-type header yourself. Your HTTP client sets it, including the multipart boundary, when you pass a FormData body.

Example response

A successful upload returns 201.

{
  "id": 142,
  "caption": "Form W-9",
  "refId": 174,
  "docType": 6,
  "fileToken": "Inj_iZ4knTu1Wi2kmRV-pJ9fvS8Njj88Y6wtdjYiljbc8mRXcvF5k22gyhhCdQJ_Ae4z@@",
  "note": "Employee changed from W-2 to 1099 contractor.",
  "clientSignatureRequired": false,
  "employeeSignatureRequired": false
}
The page was not displayed because the request entity is too large.

Response fields

FieldTypeDescription
idintegerThe document's id. Use it as DOCUMENT_ID to delete the document.
captionstringThe caption you sent.
refIdintegerIdentifier of the entity that owns the document. For employee document endpoints this is the employee identifier.
docTypeinteger (enum)The document category. See Document type values.
fileTokenstringDownload token that clients can pass to file endpoints to retrieve the document binary.
notestringThe note you sent.
clientSignatureRequiredbooleanIndicates whether an additional client-side signature is still required.
employeeSignatureRequiredbooleanIndicates whether an additional employee signature is still required.

Download a document

Each document returned by List employee documents has a fileToken. Exchange it for a download link, then request the link. The flow is the same for every file in the API and is described in Downloading Documents.


Delete a document

Permanently deletes a document from the employee.

DELETE https://api.worklio.com/wep/companies/{CLIENT_ID}/employees/{EMPLOYEE_ID}/documents/{DOCUMENT_ID}

This endpoint takes no request body.

Example request

This example deletes document 142.

require("dotenv").config();

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

async function deleteEmployeeDocument() {
  const response = await fetch(url, {
    method: "DELETE",
    headers: {
      accept: "application/json",
      "api-version": "2.0",
      authorization: `Bearer ${TOKEN}`,
      "x-api-version": "2.0"
    }
  });

  console.log(response.status);
}

deleteEmployeeDocument();
curl --request DELETE \
  --url "https://api.worklio.com/wep/companies/$CLIENT_ID/employees/$EMPLOYEE_ID/documents/142" \
  --header "accept: application/json" \
  --header "api-version: 2.0" \
  --header "authorization: Bearer $API_KEY" \
  --header "x-api-version: 2.0" \
  --include

Example response

A successful delete returns 204 with no response body. Don't parse the body. Parsing an empty body as JSON throws an error.



Did this page help you?