Skip to main content

Create a client room with welcome materials and restricted access

This example demonstrates how to onboard a client in ONLYOFFICE DocSpace. The script creates a collaboration room, creates a standard folder structure, copies welcome files from templates, configures room access for the account manager and the client, generates a room link, and logs the room information to an external CRM (placeholder).

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 ACCOUNT_MANAGER_ID = 'account_manager_user_id_here';
const CLIENT_USER_ID = 'client_user_id_here';

// Template files stored somewhere in DocSpace
const TEMPLATE_WELCOME_FILE_ID = 'template_welcome_file_id_here';
const TEMPLATE_GUIDE_FILE_ID = 'template_guide_file_id_here';

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

// Example client data (simulating external JSON)
const clientData = {
id: 'C-10045',
name: 'Acme Corporation',
email: 'contact@acme.example.com',
};

// Simple request helper (beginner-friendly)
async function docspaceRequest(method: string, path: string, body: any = null) {
const url = `${API_HOST}${path}`;

try {
const res = await fetch(url, {
method,
headers: HEADERS,
body: body ? JSON.stringify(body) : undefined,
});

if (!res.ok) {
const text = await res.text();
console.log(`Request failed. Status: ${res.status}, Message: ${text}`);
return null;
}

return res.json();
} catch (err: any) {
console.log(`Request error: ${err?.message || err}`);
return null;
}
}

function getResponseNode(data: any) {
if (!data || typeof data !== 'object') return null;
if (data.response && typeof data.response === 'object') return data.response;
return data;
}

function getId(data: any) {
const node = getResponseNode(data);
if (!node || typeof node !== 'object') return null;
return node.id != null ? Number(node.id) : null;
}

// Step 1: Create a new room for the client
async function createClientRoom(client: { name: string }) {
// POST /api/2.0/files/rooms
// Creates a collaboration room for the client and returns the room data (including room ID).
const body = {
title: `Client - ${client.name}`,
roomType: 2, // 2 = collaboration room
};

return docspaceRequest('POST', '/api/2.0/files/rooms', body);
}

// Step 2: Create folders inside the client room
async function createFolder(parentFolderId: number, title: string) {
// POST /api/2.0/files/folder/:parentFolderId
// Use the room root folder ID as the parentFolderId (in some responses it may match the room ID).
const body = { title };
return docspaceRequest('POST', `/api/2.0/files/folder/${parentFolderId}`, body);
}

// Step 3: Copy welcome materials into a target folder
async function copyTemplateFile(fileId: string, destFolderId: number, destTitle: string) {
// POST /api/2.0/files/file/:fileId/copyas
// Copies a template file into the selected destination folder inside the client room.
const body = {
destFolderId,
destTitle,
};

return docspaceRequest('POST', `/api/2.0/files/file/${fileId}/copyas`, body);
}

// Step 4: Configure room access for manager and client
async function setRoomAccess(roomId: number, managerId: string, clientId: string) {
// PUT /api/2.0/files/rooms/:roomId/share
// Updates the room share settings with two explicit entries:
// - account manager: full access (example access=4)
// - client: read-only (example access=1)
const body = {
entries: [
{ id: managerId, isGroup: false, access: 4 },
{ id: clientId, isGroup: false, access: 1 },
],
};

return docspaceRequest('PUT', `/api/2.0/files/rooms/${roomId}/share`, body);
}

// Step 5: Create a room link to send to the client
async function createRoomLink(roomId: number) {
// PUT /api/2.0/files/rooms/:roomId/links
// Creates or updates the primary external room link that can be sent to the client.
return docspaceRequest('PUT', `/api/2.0/files/rooms/${roomId}/links`, {});
}

// Step 6: Log room information in CRM (placeholder)
function logRoomToCrm(payload: any) {
// Placeholder: replace with a real CRM API request.
// Store: client info + room ID/title + room link data.
console.log('CRM payload:');
console.log(payload);
}

async function onboardClient(client: { id: string; name: string; email: string }) {
const roomData = await createClientRoom(client);
if (!roomData) return;

const roomNode = getResponseNode(roomData);
const roomId = getId(roomData);

if (!roomId) {
console.log('Cannot read room ID from API response.');
return;
}

const roomTitle =
roomNode && typeof roomNode === 'object' && roomNode.title
? String(roomNode.title)
: `Room ${roomId}`;

await createFolder(roomId, 'Invoices');
await createFolder(roomId, 'Contracts');
const deliverables = await createFolder(roomId, 'Deliverables');

const deliverablesId = getId(deliverables);
const welcomeFolderId = deliverablesId || roomId;

await copyTemplateFile(
TEMPLATE_WELCOME_FILE_ID,
welcomeFolderId,
'Welcome to your client room.pdf',
);
await copyTemplateFile(
TEMPLATE_GUIDE_FILE_ID,
welcomeFolderId,
'How to use the client portal.pdf',
);

const accessUpdated = await setRoomAccess(roomId, ACCOUNT_MANAGER_ID, CLIENT_USER_ID);
if (!accessUpdated) return;

const roomLink = await createRoomLink(roomId);

logRoomToCrm({
clientId: client.id,
clientName: client.name,
clientEmail: client.email,
roomId,
roomTitle,
roomLinkInfo: roomLink,
});

console.log(`Done. Room "${roomTitle}" (ID: ${roomId}) is ready.`);
}

(async () => {
try {
await onboardClient(clientData);
} catch (err: any) {
console.error(err?.message || err);
}
})();

Step 1: Create a client room

The script sends a POST request to /api/2.0/files/rooms to create a new collaboration room for the client. This returns the room ID used in the next steps.

async function createClientRoom(client: { name: string }) {
// POST /api/2.0/files/rooms
// Creates a collaboration room for the client and returns the room data (including room ID).
const body = {
title: `Client - ${client.name}`,
roomType: 2, // 2 = collaboration room
};

return docspaceRequest('POST', '/api/2.0/files/rooms', body);
}

Step 2: Create the standard folder structure

Then the script sends POST requests to /api/2.0/files/folder/:parentFolderId to create folders (for example, Invoices, Contracts, Deliverables) inside the room.

async function createFolder(parentFolderId: number, title: string) {
// POST /api/2.0/files/folder/:parentFolderId
// Use the room root folder ID as the parentFolderId (in some responses it may match the room ID).
const body = { title };
return docspaceRequest('POST', `/api/2.0/files/folder/${parentFolderId}`, body);
}

Step 3: Copy welcome materials into the room

Then the script sends POST requests to /api/2.0/files/file/:fileId/copyas to copy template files into the selected destination folder.

async function copyTemplateFile(fileId: string, destFolderId: number, destTitle: string) {
// POST /api/2.0/files/file/:fileId/copyas
// Copies a template file into the selected destination folder inside the client room.
const body = {
destFolderId,
destTitle,
};

return docspaceRequest('POST', `/api/2.0/files/file/${fileId}/copyas`, body);
}

Step 4: Configure room access for manager and client

Then it sends a PUT request to /api/2.0/files/rooms/:roomId/share with two entries:

  • the account manager (full access)
  • the client (read-only) This updates the room share settings and ensures the client can only view content.
async function setRoomAccess(roomId: number, managerId: string, clientId: string) {
// PUT /api/2.0/files/rooms/:roomId/share
// Updates the room share settings with two explicit entries:
// - account manager: full access (example access=4)
// - client: read-only (example access=1)
const body = {
entries: [
{ id: managerId, isGroup: false, access: 4 },
{ id: clientId, isGroup: false, access: 1 },
],
};

return docspaceRequest('PUT', `/api/2.0/files/rooms/${roomId}/share`, body);
}

Then the script sends a PUT request to /api/2.0/files/rooms/:roomId/links to generate a link that can be sent to the client.

async function createRoomLink(roomId: number) {
// PUT /api/2.0/files/rooms/:roomId/links
// Creates or updates the primary external room link that can be sent to the client.
return docspaceRequest('PUT', `/api/2.0/files/rooms/${roomId}/links`, {});
}

Step 6: Log room data in an external CRM

Finally, the script prepares a CRM payload (placeholder). Replace it with a real CRM request to store:

  • client ID/name
  • room ID/title
  • room link info
function logRoomToCrm(payload: any) {
// Placeholder: replace with a real CRM API request.
// Store: client info + room ID/title + room link data.
console.log('CRM payload:');
console.log(payload);
}