Overview
The MyToFit Health Score API calculates comprehensive health risk scores based on biometric and clinical data.
It provides three scores — Total, Wearable, and Clinical —
each mapped to a color-coded risk zone.
Score Zones
| Score Range | Color | Label | Meaning |
| 85–100 |
Blue |
Superior |
Excellent health status |
| 70–84 |
Green |
Good |
Good health status |
| 55–69 |
Yellow |
Moderate |
Moderate health risks present |
| 40–54 |
Orange |
Risk |
Elevated health risks |
| 0–39 |
Red |
High Risk |
Significant health risks detected |
Endpoints Summary
| Endpoint | Purpose | Call Frequency | Latency |
POST /calculate |
Score calculation |
Multiple times/day |
~100ms |
POST /partner/daily-refresh |
Score + AI summaries + impact drivers |
Once/day |
~3–5s |
Authentication
All requests require the following RapidAPI headers:
| Header | Value |
X-RapidAPI-Key |
Your unique API key from RapidAPI |
X-RapidAPI-Host |
mytofit-score.p.rapidapi.com |
Content-Type |
application/json |
https://mytofit-score.p.rapidapi.com
Endpoint 1: Calculate Score
Calculate MyToFit health scores. Returns all 3 scores with color-coded risk zones.
All input fields are optional — partial data is accepted and missing fields use neutral defaults.
Request Body
| Field | Type | Required | Description | Example |
age | number | No | Age in years | 35 |
sex | string | No | Biological sex (M, F, Male, Female) | "M" |
rhr | number | No | Resting Heart Rate (bpm) | 60 |
hrv_rmssd | number | No | HRV RMSSD (ms) | 50 |
vo2max | number | No | VO2 Max (ml/kg/min) | 45 |
spo2_min | number | No | Minimum nocturnal SpO2 (%) | 96 |
steps_7d_avg | number | No | Average daily steps (7-day). Also accepts steps | 8000 |
sleep_hours_7d_avg | number | No | Average sleep hours (7-day). Also accepts sleep_hours | 7.5 |
sbp | number | No | Systolic Blood Pressure (mmHg) | 120 |
triglycerides | number | No | Triglycerides (mg/dL) | 150 |
hdl | number | No | HDL Cholesterol (mg/dL) | 50 |
hba1c | number | No | HbA1c (%) | 5.5 |
smoking | string | No | Smoking status code (see below) | "never" |
alcohol | string | No | Alcohol consumption code (see below) | "none" |
Smoking Codes
| Code | Description |
never | Never smoked |
former_gt20 | Quit > 20 years ago |
former_5to_lt20 | Quit 5–20 years ago |
former_lt5 | Quit < 5 years ago |
current_lt20 | Currently smoking < 20 cigs/day |
current_20to40 | Currently smoking 20–40 cigs/day |
current_ge40 | Currently smoking > 40 cigs/day |
Alcohol Codes
| Code | Description |
none | Don't drink |
0_1_to_1_8 | 0.1 to 1.8 drinks/day |
1_8_to_3_1 | 1.8 to 3.1 drinks/day |
3_2_to_4_6 | 3.2 to 4.6 drinks/day |
gt_4_6 | > 4.6 drinks/day |
Response (200 OK)
{
"total_score": {
"score": 88.5,
"color": "Blue",
"label": "Superior",
"explanation": "Excellent health status.",
"range": "85-100"
},
"wearable_score": {
"score": 92.0,
"color": "Blue",
"label": "Superior",
"explanation": "Excellent health status.",
"range": "85-100"
},
"clinical_score": {
"score": 85.0,
"color": "Blue",
"label": "Superior",
"explanation": "Excellent health status.",
"range": "85-100"
}
}
Endpoint 2: Daily Health Refresh
Batched endpoint returning score, AI-generated wellness summaries (short + long),
top 6 score impact attributes, and echoed input values. Call once per day.
Request Body
Same input fields as /calculate, plus:
| Field | Type | Default | Description |
language |
string |
"en" |
Output language for summaries: "en" or "th" |
Response (200 OK)
{
"score": {
"total_score": { "score": 44.8, "color": "Orange", "label": "Risk", ... },
"wearable_score": { "score": 59.4, "color": "Yellow", "label": "Moderate", ... },
"clinical_score": { "score": 22.8, "color": "Red", "label": "High Risk", ... }
},
"summary_short": "Your top priority is smoking cessation.",
"summary_long": "Your health profile shows significant cardiovascular risk factors...",
"score_impact_attributes": [
{ "rank": 1, "metric": "Smoking", "current_value": "current_ge40", "score_penalty": 12.4, "domain": "Clinical" },
{ "rank": 2, "metric": "HbA1c (%)", "current_value": 5.9, "score_penalty": 8.1, "domain": "Clinical" },
{ "rank": 3, "metric": "Systolic Blood Pressure (mmHg)", "current_value": 148, "score_penalty": 6.3, "domain": "Clinical" },
{ "rank": 4, "metric": "HRV RMSSD (ms)", "current_value": 24, "score_penalty": 5.2, "domain": "Wearable" },
{ "rank": 5, "metric": "Resting Heart Rate (bpm)", "current_value": 82, "score_penalty": 3.8, "domain": "Wearable" },
{ "rank": 6, "metric": "Sleep Duration (h)", "current_value": 6.5, "score_penalty": 2.1, "domain": "Wearable" }
],
"input_values": { "age": 50, "sex": "M", "sbp": 148, ... },
"generated_at": "2026-04-14T10:00:00+00:00"
}
Score Impact Attributes
| Field | Type | Description |
rank | integer | Rank by impact (1 = highest penalty) |
metric | string | Human-readable metric name |
current_value | any | Current value of the metric |
score_penalty | number | Estimated score points lost |
domain | string | "Wearable" or "Clinical" |
Note: A maximum of 6 impact attributes are returned, sorted by score_penalty descending.
Only metrics that are actively penalizing the score appear in this list.
Integration Best Practices
Recommended call pattern:
• /calculate → Call on each app open or user interaction (score gauge widget)
• /partner/daily-refresh → Call once on first morning launch (update summaries + drivers)
Partial Data
Both endpoints accept partial input — all fields are optional. The engine always returns
all 3 scores (total, wearable, clinical) regardless of how much data is provided.
Missing fields use neutral/healthy defaults in the calculation.
Field Name Aliases
For convenience, the API accepts both naming conventions:
| Primary Name | Also Accepts |
steps_7d_avg | steps |
sleep_hours_7d_avg | sleep_hours |
Code Examples
Python
import requests
url = "https://mytofit-score.p.rapidapi.com/calculate"
payload = {
"age": 35, "sex": "M",
"sbp": 120, "triglycerides": 150, "hdl": 50, "hba1c": 5.5,
"steps_7d_avg": 8000, "sleep_hours_7d_avg": 7.5,
"rhr": 60, "vo2max": 45, "hrv_rmssd": 50, "spo2_min": 96,
"smoking": "never", "alcohol": "none"
}
headers = {
"Content-Type": "application/json",
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "mytofit-score.p.rapidapi.com"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
JavaScript / Fetch
const response = await fetch("https://mytofit-score.p.rapidapi.com/calculate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "mytofit-score.p.rapidapi.com"
},
body: JSON.stringify({
age: 35, sex: "M", sbp: 120, rhr: 60,
steps_7d_avg: 8000, sleep_hours_7d_avg: 7.5,
smoking: "never", alcohol: "none"
})
});
const data = await response.json();
console.log(data.total_score.score, data.total_score.color);
Swift (iOS)
let url = URL(string: "https://mytofit-score.p.rapidapi.com/calculate")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("YOUR_RAPIDAPI_KEY", forHTTPHeaderField: "X-RapidAPI-Key")
request.setValue("mytofit-score.p.rapidapi.com", forHTTPHeaderField: "X-RapidAPI-Host")
let body: [String: Any] = [
"age": 35, "sex": "M", "rhr": 60,
"steps_7d_avg": 8000, "smoking": "never"
]
request.httpBody = try JSONSerialization.data(withJSONObject: body)
Kotlin (Android)
val client = OkHttpClient()
val json = """{"age":35,"sex":"M","rhr":60,"steps_7d_avg":8000}"""
val body = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("https://mytofit-score.p.rapidapi.com/calculate")
.post(body)
.addHeader("X-RapidAPI-Key", "YOUR_RAPIDAPI_KEY")
.addHeader("X-RapidAPI-Host", "mytofit-score.p.rapidapi.com")
.build()
val response = client.newCall(request).execute()
cURL
curl --request POST \
--url https://mytofit-score.p.rapidapi.com/calculate \
--header 'Content-Type: application/json' \
--header 'X-RapidAPI-Host: mytofit-score.p.rapidapi.com' \
--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY' \
--data '{"age":35,"sex":"M","sbp":120,"rhr":60,"steps_7d_avg":8000,"smoking":"never"}'
Error Handling
| Status | Meaning | Action |
200 |
Success |
Parse the JSON response body |
401 |
Invalid or missing API key |
Check your X-RapidAPI-Key header |
422 |
Validation error (invalid field values) |
Check the detail array for field-level errors |
429 |
Rate limit exceeded |
Reduce call frequency or upgrade your RapidAPI plan |
500 |
Internal server error |
Retry with exponential backoff. Contact support if persistent. |
422 responses never echo submitted health data.
Only the field name and validation message are returned — no PHI leakage.