跳到主要内容

Monitor storage usage and warn when quota is near the limit

This example shows how to track DocSpace storage consumption using the API. The script reads the portal quota (total capacity) and the current used space, calculates the usage percentage, and triggers a warning (placeholder) when the usage exceeds a configured threshold. Optionally, it requests files usage statistics (if available) and prints the largest folders/files returned by the API to help you locate the main storage consumers.

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.

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

// Threshold in percent, for example: warn when 90% of quota is used
const QUOTA_THRESHOLD_PERCENT = 90;

function bytesToGb(value: any) {
const n = Number(value);
if (!Number.isFinite(n) || n <= 0) return '0 GB';
const gb = n / (1024 * 1024 * 1024);
return `${gb.toFixed(1)} GB`;
}

function pickNumber(value: any) {
const n = Number(value);
return Number.isFinite(n) ? n : null;
}

function getValue(json: any, key: string) {
if (!json || typeof json !== 'object') return null;

if (json.response && typeof json.response === 'object') {
if (json.response[key] != null) return json.response[key];
}

if (json[key] != null) return json[key];
return null;
}

function getStorageSizeBytes(quotaInfo: any) {
let v = getValue(quotaInfo, 'StorageSize');
if (v == null) v = getValue(quotaInfo, 'storageSize');
return pickNumber(v);
}

function getUsedSizeBytesFromQuota(quotaInfo: any) {
let v = getValue(quotaInfo, 'UsedSize');
if (v == null) v = getValue(quotaInfo, 'usedSize');
return pickNumber(v);
}

function getUsedSpaceBytes(usedSpaceInfo: any) {
let v = getValue(usedSpaceInfo, 'response');
if (v == null) v = getValue(usedSpaceInfo, 'usedSpace');
return pickNumber(v);
}

// Step 1: Get portal quota and space usage by modules
async function getPortalQuota() {
const url = `${API_HOST}/api/2.0/settings/quota`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get portal quota. Status code: ${res.status}, Message: ${t}`);
return null;
}

// Step 2: Get total used space of the portal
async function getPortalUsedSpace() {
const url = `${API_HOST}/api/2.0/portal/usedspace`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get portal used space. Status code: ${res.status}, Message: ${t}`);
return null;
}

// Step 3: Get used space of files in root folders (to find heavy areas)
async function getFilesUsedSpace() {
const url = `${API_HOST}/api/2.0/files/filesusedspace`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get files used space. Status code: ${res.status}, Message: ${t}`);
return null;
}

function getTopHeavyItems(items: any, limit = 10) {
if (!Array.isArray(items)) return [];

const normalized: { path: string; size: number }[] = [];

for (const item of items) {
if (!item || typeof item !== 'object') continue;

const path = item.path || item.Path || '';
const sizeRaw = item.size ?? item.Size;

const size = Number(sizeRaw);
if (!path || !Number.isFinite(size)) continue;

normalized.push({ path: String(path), size });
}

normalized.sort((a, b) => b.size - a.size);
return normalized.slice(0, limit);
}

function sendQuotaWarning(message: string) {
console.log('[WARNING]', message);
// Replace this placeholder with your notification system (email, Slack webhook, etc.)
}

async function checkDiskUsage() {
const quotaInfo = await getPortalQuota();
const usedSpaceInfo = await getPortalUsedSpace();
const filesUsageInfo = await getFilesUsedSpace();

if (!quotaInfo || !usedSpaceInfo) {
console.log('Usage check skipped because quota or used space data is missing.');
return;
}

const totalBytes = getStorageSizeBytes(quotaInfo);

let usedBytes = getUsedSizeBytesFromQuota(quotaInfo);
if (usedBytes == null) {
usedBytes = getUsedSpaceBytes(usedSpaceInfo);
}

if (!Number.isFinite(totalBytes) || !Number.isFinite(usedBytes)) {
console.log('Cannot calculate percentage: totalBytes or usedBytes is missing.');
return;
}

const percentUsed = (usedBytes / totalBytes) * 100;

console.log('\n=== DocSpace storage usage report ===');
console.log(`Total quota: ${bytesToGb(totalBytes)}`);
console.log(`Used space: ${bytesToGb(usedBytes)} (${percentUsed.toFixed(1)}%)`);

if (percentUsed >= QUOTA_THRESHOLD_PERCENT) {
const warningMessage =
`DocSpace storage usage has reached ${percentUsed.toFixed(1)}% of the quota. ` +
`Please clean up or increase the quota.`;
sendQuotaWarning(warningMessage);
}

const items =
(filesUsageInfo && filesUsageInfo.response && filesUsageInfo.response.StorageUsage) ||
(filesUsageInfo && filesUsageInfo.response) ||
(filesUsageInfo && filesUsageInfo.storageUsage) ||
filesUsageInfo;

const topHeavy = getTopHeavyItems(items, 10);

if (topHeavy.length > 0) {
console.log('\nTop heavy folders/files (by size):');
for (let i = 0; i < topHeavy.length; i++) {
console.log(`${i + 1}. ${topHeavy[i].path} - ${bytesToGb(topHeavy[i].size)}`);
}
} else {
console.log('\nNo detailed per-folder/file usage data found in filesusedspace response.');
}

console.log('\nDisk usage monitoring check finished.');
}

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

Step 1: Retrieve portal quota

A GET request is sent to /api/2.0/settings/quota to retrieve the portal quota.

The response typically includes:

  • total available storage size
  • used size (depending on portal configuration)
async function getPortalQuota() {
const url = `${API_HOST}/api/2.0/settings/quota`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get portal quota. Status code: ${res.status}, Message: ${t}`);
return null;
}

Step 2: Retrieve portal used space

A GET request is sent to /api/2.0/portal/usedspace to retrieve the total used space value. This value is used as a fallback if the quota endpoint does not provide UsedSize.

async function getPortalUsedSpace() {
const url = `${API_HOST}/api/2.0/portal/usedspace`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get portal used space. Status code: ${res.status}, Message: ${t}`);
return null;
}

Step 3: Find "heavy" folders and files

A GET request is sent to /api/2.0/files/filesusedspace to retrieve per-folder usage data. The script sorts the items by size and prints the top 10 biggest entries.

async function getFilesUsedSpace() {
const url = `${API_HOST}/api/2.0/files/filesusedspace`;
const res = await fetch(url, { method: 'GET', headers: HEADERS });

if (res.ok) {
return res.json();
}

const t = await res.text();
console.log(`Failed to get files used space. Status code: ${res.status}, Message: ${t}`);
return null;
}