apihow-toglobalsizingdeveloper-guide

How to Serve Accurate Size Recommendations Across Multiple World Regions

· 5 min read · Martin Hejda

A 175 cm, 68 kg woman in Seoul and a 175 cm, 68 kg woman in Stockholm have statistically different body proportions. Not dramatically different — but enough that the same size recommendation algorithm, applied to the same input values, can return a different optimal size depending on where the population data was calibrated.

DimensionsPot addresses this through regional calibration profiles. The API accepts a target_region and input_origin_region parameter that shifts the underlying statistical model toward the body proportion norms of a specific global population. Getting this parameter right — and choosing how to determine it for each user — is the subject of this guide.


The seven regional profiles

ProfilePopulation
GLOBALPopulation-weighted world average — use as fallback when region is unknown
NORTH_AMERICAUS, Canada, Mexico
EUROPEWestern and Eastern Europe
ASIA_PACIFICEast and Southeast Asia, Pacific
SOUTH_ASIAIndia, Pakistan, Bangladesh, Sri Lanka, Nepal
LATIN_AMERICASouth America, Central America, Caribbean
AFRICA_MIDDLE_EASTSub-Saharan Africa, North Africa, Middle East

The differences between profiles are most pronounced in shoulder width, hip-to-waist ratio, and torso depth. For a given height/weight combination, ASIA_PACIFIC profiles tend to return narrower shoulder widths and different hip distributions than NORTH_AMERICA or EUROPE. The confidence scores for dimensions most affected by regional variation will reflect this.


Three strategies for region detection

Strategy 1: Country code from IP geolocation

Fast, automatic, works without user input. The downside: inaccurate for VPN users, expatriates, and travelers — three populations that include many online shoppers.

// Using a geolocation service — many options: ipapi.co, ipinfo.io, Cloudflare headers
async function regionFromIp(ip) {
  try {
    const res = await fetch(`https://ipapi.co/${ip}/country/`);
    const countryCode = await res.text();
    return countryToRegion(countryCode.trim());
  } catch {
    return 'GLOBAL';
  }
}

// When using Cloudflare or Vercel — the country code is in request headers
function regionFromCloudflareHeaders(req) {
  const country = req.headers['cf-ipcountry'] ?? req.headers['x-vercel-ip-country'];
  return countryToRegion(country);
}

Strategy 2: Browser locale

Available without an external service. Less reliable than IP geolocation for region — en-US from a user in Germany who set their browser to English gives you nothing useful.

// Accept-Language: en-US,en;q=0.9 → country code "US" → NORTH_AMERICA
function regionFromAcceptLanguage(acceptLanguage) {
  const primaryLocale = (acceptLanguage ?? '').split(',')[0].trim();
  const parts = primaryLocale.split('-');
  const countryCode = parts.length > 1 ? parts[parts.length - 1] : null;
  return countryCode ? countryToRegion(countryCode.toUpperCase()) : 'GLOBAL';
}

The most accurate approach. Show users a region selector during the sizing flow. Label it as body type calibration, not location — it’s more honest and explains the purpose.

<label for="body-region">Body type calibration</label>
<select id="body-region" name="region">
  <option value="GLOBAL">Global average (default)</option>
  <option value="NORTH_AMERICA">North America</option>
  <option value="EUROPE">Europe</option>
  <option value="ASIA_PACIFIC">Asia Pacific</option>
  <option value="SOUTH_ASIA">South Asia</option>
  <option value="LATIN_AMERICA">Latin America</option>
  <option value="AFRICA_MIDDLE_EAST">Africa & Middle East</option>
</select>
<small>This calibrates the prediction to population norms where you live.
       Your location is not stored.</small>

For returning users, persist their last selection (the region preference, not their location data) and pre-fill it.


The country-to-region mapping

const COUNTRY_TO_REGION = {
  // North America
  US: 'NORTH_AMERICA', CA: 'NORTH_AMERICA', MX: 'NORTH_AMERICA',

  // Europe
  GB: 'EUROPE', DE: 'EUROPE', FR: 'EUROPE', IT: 'EUROPE', ES: 'EUROPE',
  PT: 'EUROPE', NL: 'EUROPE', BE: 'EUROPE', AT: 'EUROPE', CH: 'EUROPE',
  SE: 'EUROPE', NO: 'EUROPE', DK: 'EUROPE', FI: 'EUROPE', PL: 'EUROPE',
  CZ: 'EUROPE', SK: 'EUROPE', HU: 'EUROPE', RO: 'EUROPE', GR: 'EUROPE',
  IE: 'EUROPE', HR: 'EUROPE', RS: 'EUROPE', BG: 'EUROPE', UA: 'EUROPE',

  // Asia Pacific
  CN: 'ASIA_PACIFIC', JP: 'ASIA_PACIFIC', KR: 'ASIA_PACIFIC',
  TW: 'ASIA_PACIFIC', HK: 'ASIA_PACIFIC', SG: 'ASIA_PACIFIC',
  AU: 'ASIA_PACIFIC', NZ: 'ASIA_PACIFIC', TH: 'ASIA_PACIFIC',
  VN: 'ASIA_PACIFIC', ID: 'ASIA_PACIFIC', MY: 'ASIA_PACIFIC',
  PH: 'ASIA_PACIFIC',

  // South Asia
  IN: 'SOUTH_ASIA', PK: 'SOUTH_ASIA', BD: 'SOUTH_ASIA',
  LK: 'SOUTH_ASIA', NP: 'SOUTH_ASIA',

  // Latin America
  BR: 'LATIN_AMERICA', AR: 'LATIN_AMERICA', CO: 'LATIN_AMERICA',
  CL: 'LATIN_AMERICA', PE: 'LATIN_AMERICA', VE: 'LATIN_AMERICA',
  EC: 'LATIN_AMERICA', BO: 'LATIN_AMERICA', PY: 'LATIN_AMERICA',
  UY: 'LATIN_AMERICA', GT: 'LATIN_AMERICA', CR: 'LATIN_AMERICA',

  // Africa & Middle East
  NG: 'AFRICA_MIDDLE_EAST', ZA: 'AFRICA_MIDDLE_EAST', EG: 'AFRICA_MIDDLE_EAST',
  SA: 'AFRICA_MIDDLE_EAST', AE: 'AFRICA_MIDDLE_EAST', KE: 'AFRICA_MIDDLE_EAST',
  GH: 'AFRICA_MIDDLE_EAST', ET: 'AFRICA_MIDDLE_EAST', TZ: 'AFRICA_MIDDLE_EAST',
  MA: 'AFRICA_MIDDLE_EAST', IL: 'AFRICA_MIDDLE_EAST', TR: 'AFRICA_MIDDLE_EAST',
};

function countryToRegion(countryCode) {
  return COUNTRY_TO_REGION[countryCode?.toUpperCase()] ?? 'GLOBAL';
}

Wiring it into the API call

Both input_origin_region and target_region should receive the same value in most use cases. input_origin_region tells the model which regional reference population to use for the prediction; target_region applies calibration to the output.

app.post('/api/size', async (req, res) => {
  const { gender, height_cm, weight_kg, region: userRegion } = req.body;

  // Fallback chain: explicit user choice → IP detection → global
  const region = userRegion
    ?? regionFromCloudflareHeaders(req)
    ?? 'GLOBAL';

  const heightMm = Math.round(parseFloat(height_cm) * 10);
  const weightKg = parseFloat(weight_kg);

  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: gender.toLowerCase(),
          input_origin_region: region,   // ← regional calibration
        },
        anchors: {
          body_height: heightMm,
          body_mass: weightKg,
        },
      },
      output_settings: {
        calculation: {
          calculation_model: 'AUTO',
          target_region: region,          // ← same value
          body_build_type: 'CIVILIAN',
        },
        requested_dimensions: { bundle: 'TORSO' },
        output_format: {
          unit_system: 'metric',
          confidence_score_threshold: 0,
          include_range_95: false,
          include_iso_codes: false,
        },
      },
    }),
  });

  const data = await apiRes.json();
  // ... size chart logic
});

Caching with region awareness

The cache key must include the region. Two identical height/weight inputs with different regions produce different outputs:

// WRONG — ignores region, returns incorrect cached results
const cacheKey = `${gender}-${heightMm}-${weightKg}`;

// CORRECT — region is part of the cache key
const cacheKey = `${gender}-${heightMm}-${weightKg}-${region}`;

Testing across regions

Verify that your implementation is actually applying the regional profile correctly by comparing outputs for the same input across two regions that differ most (ASIA_PACIFIC vs EUROPE tends to produce the largest deltas in shoulder breadth and hip ratios):

// Verification test — run once during development
const input = { gender: 'female', height_cm: 165, weight_kg: 58 };

const [apac, eu] = await Promise.all([
  getDimensions({ ...input, region: 'ASIA_PACIFIC' }),
  getDimensions({ ...input, region: 'EUROPE' }),
]);

console.log('Shoulder breadth — ASIA_PACIFIC:', apac.body_dimensions?.biacromial_breadth?.value);
console.log('Shoulder breadth — EUROPE:', eu.body_dimensions?.biacromial_breadth?.value);
// These should differ. If they're identical, check that region is being passed correctly.

If the values are identical, the most common cause is a cache hit using a key that doesn’t include the region.


When GLOBAL is the right choice

For a single-market business shipping only to one country, there’s no reason to implement region detection — use that country’s profile directly and hardcode it. Region detection overhead only makes sense if you’re genuinely serving multiple markets where body proportion differences would affect size recommendations.

For a business just starting to go international, start with GLOBAL. The results are less precise than a calibrated profile for a specific market, but correct for most users. Add explicit regional detection when you have a significant user base in a specific region and can verify the improvement in size accuracy.

Try DimensionsPot

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

Get API on RapidAPI