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
| Profile | Population |
|---|---|
GLOBAL | Population-weighted world average — use as fallback when region is unknown |
NORTH_AMERICA | US, Canada, Mexico |
EUROPE | Western and Eastern Europe |
ASIA_PACIFIC | East and Southeast Asia, Pacific |
SOUTH_ASIA | India, Pakistan, Bangladesh, Sri Lanka, Nepal |
LATIN_AMERICA | South America, Central America, Caribbean |
AFRICA_MIDDLE_EAST | Sub-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';
}
Strategy 3: Explicit user selection (recommended)
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.