ergonomicsworkplacehow-todeveloper-guide

How to Build an Ergonomic Workspace Setup Calculator

· 5 min read · Martin Hejda

Ergonomic workspace guidance is almost always generic: “adjust your chair so your feet are flat on the floor,” “your monitor should be at eye level.” These rules are correct in principle and useless in practice, because the correct chair height for a 155 cm person is fundamentally different from the correct chair height for a 190 cm person.

Personalised ergonomic calculators have existed as spreadsheet tools for years. Building one as a web application — for HR portals, remote work equipment programmes, or office onboarding flows — requires body dimensions that most users don’t know off the top of their head. Except they do know two: height and weight. From those, DimensionsPot returns the seated and standing dimensions that drive every ergonomic calculation.


Which dimensions drive ergonomic recommendations

The FULL_BODY bundle includes the seated posture dimensions that matter most for workspace setup:

Dimension IDDefinitionErgonomic application
popliteal_heightFloor to back of knee when seatedChair seat height
elbow_rest_heightSeat surface to elbow crease at restDesk height for keyboard/mouse work
eye_height_sittingSeat surface to eye centre when seatedMonitor height
sitting_heightSeat surface to top of head when seatedHeadroom, overhead shelf clearance
shoulder_widthBiacromial breadthMinimum chair width, armrest span
arm_lengthShoulder to fingertipComfortable monitor distance

These are ISO 7250-1 standard seated dimensions, measured with the subject seated upright with thighs horizontal. Verify exact dimension_id values against the Data Dictionary before deploying.


Step 1: Server endpoint

// ergonomics.js — Express endpoint
const express = require('express');
const router  = express.Router();

const API_URL     = 'https://dimensionspot-bodysize-engine.p.rapidapi.com/v1/predict';
const RAPIDAPI_KEY = process.env.RAPIDAPI_KEY;

const cache = new Map();

function buildRecommendations(dims) {
  const {
    popliteal_height   = 0,
    elbow_rest_height  = 0,
    eye_height_sitting = 0,
    sitting_height     = 0,
    shoulder_width     = 0,
    arm_length         = 0,
  } = dims;

  // All calculations in mm; convert to cm for display
  const chairHeightMm     = popliteal_height;
  // Desk height = chair seat height + elbow rest height (elbows at ~90°)
  const deskHeightMm      = chairHeightMm + elbow_rest_height;
  // Monitor top = chair + eye height + ~30mm for slight downward gaze
  const monitorTopMm      = chairHeightMm + eye_height_sitting + 30;
  // Monitor distance: 1.2× arm length is a good general starting point
  const monitorDistMm     = Math.round(arm_length * 1.2);
  // Chair width: shoulder width + 60mm clearance each side
  const chairWidthMinMm   = shoulder_width + 120;

  const toRange = (mm, ±) => ({
    min: Math.round((mm - ±) / 10),
    max: Math.round((mm + ±) / 10),
    recommended: Math.round(mm / 10),
    unit: 'cm',
  });

  return {
    chair: {
      seat_height:   toRange(chairHeightMm, 25),
      min_seat_width: Math.round(chairWidthMinMm / 10),
    },
    desk: {
      surface_height: toRange(deskHeightMm, 20),
      note: 'For seated keyboard/mouse work with elbows at approximately 90°.',
    },
    monitor: {
      top_height:    toRange(monitorTopMm, 30),
      distance_from_eyes: toRange(monitorDistMm, 80),
      note: 'Top of monitor at or slightly below eye level. Distance is a starting point — adjust based on font size preference.',
    },
    standing_desk: {
      height: toRange(popliteal_height + elbow_rest_height + chairHeightMm * 0, 0),
      // Standing desk height ≈ elbow height from floor
      // elbow_height_standing not always in bundle; approximate:
      note: 'Standing desk: set so elbows are at approximately 90° when standing. Calculate from your standing elbow height.',
    },
  };
}

router.post('/workspace', async (req, res) => {
  const { gender, height_cm, weight_kg } = req.body;

  if (!gender || !height_cm || !weight_kg) {
    return res.status(400).json({ error: 'gender, height_cm, and weight_kg are required' });
  }

  const heightMm = Math.round(parseFloat(height_cm) * 10);
  const weightKg = parseFloat(weight_kg);
  const cacheKey = `${gender}-${heightMm}-${weightKg}`;

  if (!cache.has(cacheKey)) {
    const apiRes = await fetch(API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-rapidapi-key': RAPIDAPI_KEY,
        'x-rapidapi-host': 'dimensionspot-bodysize-engine.p.rapidapi.com',
      },
      body: JSON.stringify({
        input_data: {
          input_unit_system: 'metric',
          subject: { gender, input_origin_region: 'GLOBAL' },
          anchors: { body_height: heightMm, body_mass: weightKg },
        },
        output_settings: {
          calculation: {
            calculation_model: 'AUTO',
            target_region: 'GLOBAL',
            body_build_type: 'CIVILIAN',
          },
          requested_dimensions: { bundle: 'FULL_BODY' },
          output_format: {
            unit_system: 'metric',
            confidence_score_threshold: 0,
            include_range_95: false,
            include_iso_codes: false,
          },
        },
      }),
    });

    if (!apiRes.ok) return res.status(502).json({ error: 'Prediction service unavailable' });

    const data = await apiRes.json();
    const dims = Object.fromEntries(
      Object.entries(data.body_dimensions).map(([key, d]) => [key, d.value])
    );
    cache.set(cacheKey, dims);
  }

  const dims = cache.get(cacheKey);
  res.json(buildRecommendations(dims));
});

module.exports = router;

Step 2: Example response

For a 168 cm, 62 kg female employee:

{
  "chair": {
    "seat_height":    { "min": 38, "max": 43, "recommended": 40, "unit": "cm" },
    "min_seat_width": 52
  },
  "desk": {
    "surface_height": { "min": 63, "max": 67, "recommended": 65, "unit": "cm" },
    "note": "For seated keyboard/mouse work with elbows at approximately 90°."
  },
  "monitor": {
    "top_height":         { "min": 97, "max": 103, "recommended": 100, "unit": "cm" },
    "distance_from_eyes": { "min": 54, "max": 70, "recommended": 62, "unit": "cm" },
    "note": "Top of monitor at or slightly below eye level."
  }
}

The ±ranges are intentional. Ergonomic standards (ISO 9241-5, OSHA guidelines) acknowledge that comfortable posture varies by task and preference. Giving a range rather than a single number is more honest and more useful — it tells the employee what to aim for, not a single millimetre to hit.


Step 3: HR bulk assessment

For companies deploying remote work equipment to multiple employees, run the calculator in batch from an HR data export:

const fs   = require('fs');
const Papa = require('papaparse'); // npm install papaparse

// Input CSV: employee_id, gender, height_cm, weight_kg
const csv = fs.readFileSync('employees.csv', 'utf-8');
const { data: employees } = Papa.parse(csv, { header: true });

async function generateAllRecommendations() {
  const results = [];

  // Process in batches of 10 to respect rate limits
  for (let i = 0; i < employees.length; i += 10) {
    const batch = employees.slice(i, i + 10);
    const batchResults = await Promise.all(
      batch.map(async (emp) => {
        const res = await fetch('https://your-server.com/workspace', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            gender: emp.gender,
            height_cm: emp.height_cm,
            weight_kg: emp.weight_kg,
          }),
        });
        const recs = await res.json();
        return {
          employee_id:         emp.employee_id,
          chair_height_cm:     recs.chair.seat_height.recommended,
          desk_height_cm:      recs.desk.surface_height.recommended,
          monitor_top_cm:      recs.monitor.top_height.recommended,
          monitor_distance_cm: recs.monitor.distance_from_eyes.recommended,
          chair_width_min_cm:  recs.chair.min_seat_width,
        };
      })
    );
    results.push(...batchResults);
    if (i + 10 < employees.length) await new Promise(r => setTimeout(r, 150));
  }

  // Output CSV
  const output = Papa.unparse(results);
  fs.writeFileSync('workspace_recommendations.csv', output);
  console.log(`Generated recommendations for ${results.length} employees`);
}

generateAllRecommendations();

Important caveats

Seated dimensions are population-level estimates. The API predicts seated dimensions from standing height and weight using population regression. For most users the predictions will be within 15–25 mm of measured values — good enough for chair and desk height recommendations, where adjustments are made in increments of 25–50 mm anyway.

Individual variation exists. People with unusually long or short torsos relative to their legs may find predictions slightly off. Adding a “does this feel right?” validation step in the UI — asking the employee to confirm whether the chair feels correctly set — improves accuracy at no cost.

Adjustable furniture is the target. The output of this calculator is meaningless if the furniture has no adjustment range. The calculator tells employees how to set adjustable equipment; it doesn’t substitute for having adjustable equipment in the first place.

Try DimensionsPot

Free tier — 100 requests/month, no credit card required.

Get API on RapidAPI