The most common error when integrating a body measurement API is a unit mistake. Not a wrong endpoint, not a missing header — a unit mistake. Specifically: sending height in centimeters when the API expects millimeters, or sending weight in pounds when it expects kilograms.
A 422 validation error is the obvious outcome. But the subtler problem is when the values pass validation because they happen to fall within a plausible range — and you get predictions for a person who is effectively a different height from your user.
This guide covers unit handling completely.
Why millimeters?
ISO 7250-1 — the international standard for human body measurement definitions and landmarks — specifies all linear body measurements in millimeters. This is the standard used by ergonomists, industrial designers, and anthropometric researchers globally.
Using millimeters internally (and as the API’s canonical unit) means the output is directly usable for ISO-compliant documentation and product certification. It also avoids decimal ambiguity: 178.5cm requires a decimal point, but 1785mm is an integer. Most anthropometric measurements are naturally expressed to the nearest millimeter in professional contexts.
The practical implication: whatever unit your users enter in your UI, you convert to mm before calling the API.
The metric input format
"input_data": {
"input_unit_system": "metric",
"subject": { "gender": "female", "input_origin_region": "EUROPE" },
"anchors": {
"body_height": 1650, # mm — 165cm × 10
"body_mass": 62.0 # kg — no conversion needed
}
}
Metric rules:
body_height: always in millimeters (multiply cm by 10)body_mass: always in kilograms- All circumference anchors: always in millimeters
The imperial input format
For apps serving users who think in feet/inches and pounds, set input_unit_system: "imperial" and the API handles conversion automatically:
"input_data": {
"input_unit_system": "imperial",
"subject": { "gender": "male", "input_origin_region": "GLOBAL" },
"anchors": {
"body_height": 70.0, # inches — 5'10" = 70 inches
"body_mass": 180.0 # pounds
}
}
Internally, the API converts:
- All linear measurements:
inches × 25.4→ mm body_mass:pounds ÷ 2.20462→ kg
The conversion is applied before validation, so the bounds check runs on metric values. For imperial, body_height 70 inches = 1778mm — within the valid range of 400–3000mm.
Output unit system
The input and output unit systems are independent. You can send imperial input and receive metric output, or send metric input and receive imperial output:
"output_format": {
"unit_system": "imperial", # "metric" or "imperial"
"include_range_95": True
}
With unit_system: "imperial":
- Linear dimensions return in inches (millimeters ÷ 25.4)
body_massestimates return in poundsrange_95bounds are also converted to the output unit
"chest_circumference": {
"value": 36.2,
"unit": "in",
"range_95": [34.1, 38.3]
}
For US-market fashion apps, this is often the most user-friendly output format — you can display “36.2 inches” directly without client-side conversion.
Handling mixed UI inputs
Users often enter height in feet and inches separately — 5'10" rather than 70. Your UI should collect these separately and convert before the API call:
function feetInchesToMm(feet: number, inches: number): number {
const totalInches = feet * 12 + inches;
return totalInches * 25.4;
}
// Or if sending imperial:
function feetInchesToTotalInches(feet: number, inches: number): number {
return feet * 12 + inches;
}
For the imperial input path, you can also send the total inches directly — the API accepts decimal inches for body_height.
The centimeter trap
The most common mistake deserves its own section.
A user enters 175 (centimeters). You send body_height: 175 with input_unit_system: "metric". The API validator checks: is 175 within the range [400, 3000] mm? Yes — 175mm is roughly the height of a newborn. The request succeeds. You receive predictions for a 17.5cm person.
The predictions will look plausible because the model is well-regularized and won’t produce obviously nonsensical numbers — it will simply predict a very small person. Your downstream sizing logic might display nonsensical results without triggering an error.
The fix is a simple conversion guard:
def safe_height_mm(user_input_cm: float) -> float:
"""Convert cm input to mm for API. Validate range before sending."""
mm = user_input_cm * 10
if not (1400 <= mm <= 2200): # reasonable adult range
raise ValueError(f"Height {user_input_cm}cm is outside expected range 140–220cm")
return mm
Add your own range validation before the API call — catching the unit mistake at your layer gives a much clearer error message than a 422 from the API.
Circumference anchor units
If you’re using optional circumference anchors (waist, hip, chest, wrist, neck) to improve prediction accuracy, these are also in millimeters for metric input or inches for imperial input.
Common user inputs for waist:
- “32 inch jeans” → 32 inches → 812.8mm
- “80cm waist” → 800mm
- A cloth tape measure reading in cm
# Convert common user inputs
waist_jeans_size_inches = 32
waist_mm = waist_jeans_size_inches * 25.4 # 812.8mm
# Or metric
waist_cm = 80
waist_mm = waist_cm * 10 # 800mm
For the waist_circumference_omphalion anchor (which corresponds to the navel-level measurement used in clothing), the jeans waist size in inches is a reasonable proxy for US users. It’s slightly different from the anatomical omphalion measurement, but close enough that it improves prediction accuracy over height + weight alone.
Quick reference
| Measurement | Metric unit | Imperial unit | Conversion |
|---|---|---|---|
| body_height | mm | in | mm = in × 25.4 |
| body_mass | kg | lb | kg = lb ÷ 2.20462 |
| All circumferences | mm | in | mm = in × 25.4 |
| foot_length | mm | in | mm = in × 25.4 |
| hand_length | mm | in | mm = in × 25.4 |
One API parameter controls input conversion (input_unit_system). A separate one controls output format (output_format.unit_system). They are independent.
Unit handling is plumbing — unglamorous but essential. Get it right once in a utility function or middleware layer, and you’ll never think about it again.