Skip to main content

Onboard an employee into a shared "Employees" folder

This example demonstrates how to prepare a structured workspace for a new employee in ONLYOFFICE DocSpace using the API.

The workflow creates a personal folder inside a shared Employees directory, builds a standard subfolder structure, copies starter documents from templates, and generates an external access link. Optionally, the example also shows how a DocSpace user can be created as part of the same onboarding process.

This approach helps standardize employee document storage and simplifies access management during onboarding.

Before you start

  1. Replace https://yourportal.onlyoffice.com and YOUR_API_KEY with your actual DocSpace portal URL and API key. Ensure you have the necessary data and permissions to perform these operations.
  2. Before you can make requests to the API, you need to authenticate. Check out the Personal access tokens page to learn how to obtain and use access tokens.
Full example
// Set API base URL
const API_HOST = process.env.DOCSPACE_API_HOST; // Set DOCSPACE_API_HOST in env (recommended). For quick tests you can temporarily paste your portal URL here.
const API_KEY = process.env.DOCSPACE_API_KEY; // Set DOCSPACE_API_KEY in env (recommended). For quick tests you can temporarily paste token here.

// IDs from your DocSpace
const EMPLOYEES_FOLDER_ID = 'employees_folder_id_here'; // Shared "Employees" folder
const TEMPLATE_NDA_FILE_ID = 'template_nda_file_id_here';
const TEMPLATE_POLICIES_FILE_ID = 'template_policies_file_id_here';

// Headers with API key for authentication
const HEADERS = {
Accept: 'application/json',
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
};

// Step 1: Create a new user in DocSpace
async function createEmployeeUser(employee: { email: string; firstName: string; lastName: string }) {

const url = `${API_HOST}/api/2.0/people/`;

const body = {
email: employee.email,
firstName: employee.firstName,
lastName: employee.lastName,
// Add other fields if needed:
// title: employee.title,
// department: employee.department,
};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`User creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
const userId = json?.response?.id ?? json?.id ?? null;
console.log(`Step 1 completed: user created (ID: ${userId}).`);
return json;
}

// Step 2: Create a personal folder inside the shared Employees folder
async function createEmployeeFolder(parentFolderId: string, folderTitle: string) {
const url = `${API_HOST}/api/2.0/files/folder/${parentFolderId}`;
const body = { title: folderTitle };

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`Folder creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
const folderId = json?.response?.id ?? json?.id ?? null;
console.log(`Step 2 completed: folder created "${folderTitle}" (ID: ${folderId}).`);
return json;
}

// Helper: Create a subfolder by name
async function createSubfolder(parentFolderId: string, subfolderTitle: string) {
return createEmployeeFolder(parentFolderId, subfolderTitle);
}

// Step 4: Copy a template file into a folder
async function copyTemplateFile(fileId: string, destFolderId: string, destTitle: string, toForm = false) {
const url = `${API_HOST}/api/2.0/files/file/${fileId}/copyas`;

const body = {
destFolderId,
destTitle,
toForm,
};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`File copy failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
console.log(`Step 4 completed: file copied "${destTitle}".`);
return json;
}

// Step 5: Create an external link to the employee folder
async function createEmployeeFolderExternalLink(folderId: string) {
const url = `${API_HOST}/api/2.0/files/folder/${folderId}/link`;

// For a basic example, we send an empty body and use default link settings.
const body = {};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`External link creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
console.log('Step 5 completed: external link created.');
return json;
}

// Main onboarding workflow
(async () => {
try {
// Example source data (you can load it from any external system as JSON)
const employee = {
email: 'new.employee@example.com',
firstName: 'New',
lastName: 'Employee',
};

// Step 1: Create user
const user = await createEmployeeUser(employee);
if (!user) return;

// Step 2: Create employee folder
const employeeFolderTitle = `${employee.lastName} ${employee.firstName}`;
const employeeFolder = await createEmployeeFolder(EMPLOYEES_FOLDER_ID, employeeFolderTitle);
if (!employeeFolder) return;

const employeeFolderId = employeeFolder?.response?.id ?? employeeFolder?.id ?? null;
if (!employeeFolderId) {
console.log('Could not determine the new folder ID from the response.');
return;
}

// Step 3: Create standard subfolder structure
const contractsFolder = await createSubfolder(employeeFolderId, 'Contracts');
const tasksFolder = await createSubfolder(employeeFolderId, 'Tasks');
const hrDocsFolder = await createSubfolder(employeeFolderId, 'HR docs');

const contractsFolderId = contractsFolder?.response?.id ?? contractsFolder?.id ?? null;
const hrDocsFolderId = hrDocsFolder?.response?.id ?? hrDocsFolder?.id ?? null;

// Step 4: Copy starter documents
if (contractsFolderId) {
await copyTemplateFile(TEMPLATE_NDA_FILE_ID, contractsFolderId, 'NDA - to sign.docx');
}

if (hrDocsFolderId) {
await copyTemplateFile(TEMPLATE_POLICIES_FILE_ID, hrDocsFolderId, 'Company Policies.docx');
}

// Step 5: Create external link
const linkInfo = await createEmployeeFolderExternalLink(employeeFolderId);
if (!linkInfo) return;

console.log('Onboarding completed. Folder external link details:');
console.log(JSON.stringify(linkInfo, null, 2));
} catch (err: any) {
console.error(err?.message || err);
}
})();

Step 1: Create an employee user

A POST request is sent to /api/2.0/people/ to create a new DocSpace user.

The request body includes:

  • email: The employee email address.
  • firstName: The employee first name.
  • lastName: The employee last name.

The API returns a user object. The new user ID is required if you want to connect future onboarding steps to this user.

async function createEmployeeUser(employee: { email: string; firstName: string; lastName: string }) {

const url = `${API_HOST}/api/2.0/people/`;

const body = {
email: employee.email,
firstName: employee.firstName,
lastName: employee.lastName,
// Add other fields if needed:
// title: employee.title,
// department: employee.department,
};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`User creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
const userId = json?.response?.id ?? json?.id ?? null;
console.log(`Step 1 completed: user created (ID: ${userId}).`);
return json;
}

Step 2: Create a personal folder in the "Employees" folder

A POST request is sent to /api/2.0/files/folder/:parentId to create a personal folder inside the shared "Employees" folder.

The request body includes:

  • title: folder title (for example, LastName FirstName).

The API returns a folder object with the new folder ID. This folder ID is required for all next steps.

async function createEmployeeFolder(parentFolderId: string, folderTitle: string) {
const url = `${API_HOST}/api/2.0/files/folder/${parentFolderId}`;
const body = { title: folderTitle };

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`Folder creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
const folderId = json?.response?.id ?? json?.id ?? null;
console.log(`Step 2 completed: folder created "${folderTitle}" (ID: ${folderId}).`);
return json;
}

Step 3: Create standard subfolder structure

This step creates a predictable folder layout inside the employee folder (for example: Contracts, Tasks, HR docs). Each subfolder is created using the same request as in Step 2, changing only the title.

async function createSubfolder(parentFolderId: string, subfolderTitle: string) {
return createEmployeeFolder(parentFolderId, subfolderTitle);
}

Step 4: Copy starter documents from templates

A POST request is sent to /api/2.0/files/file/:fileId/copyas to copy template files into the correct subfolders.

The request body includes:

  • destFolderId: Destination folder ID (where the file should be placed).
  • destTitle: The file name in the destination folder.
  • toForm: Optional flag (default false) if you want to convert the copied file into a form.

This step typically copies:

  • An NDA template into Contracts
  • A company policies template into HR docs
async function copyTemplateFile(fileId: string, destFolderId: string, destTitle: string, toForm = false) {
const url = `${API_HOST}/api/2.0/files/file/${fileId}/copyas`;

const body = {
destFolderId,
destTitle,
toForm,
};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`File copy failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
console.log(`Step 4 completed: file copied "${destTitle}".`);
return json;
}

A POST request is sent to /api/2.0/files/folder/:folderId/linkto generate an external link to the employee folder.

For a basic scenario, the request body can be empty, so the API uses default link settings.

The response includes link information that can be shared with the employee or used in your HR workflow (for example, sending the link by email).

async function createEmployeeFolderExternalLink(folderId: string) {
const url = `${API_HOST}/api/2.0/files/folder/${folderId}/link`;

// For a basic example, we send an empty body and use default link settings.
const body = {};

const res = await fetch(url, { method: 'POST', headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) {
const t = await res.text();
console.log(`External link creation failed. Status code: ${res.status}, Message: ${t}`);
return null;
}

const json = await res.json();
console.log('Step 5 completed: external link created.');
return json;
}