MyToFit Health Score API

Developer Integration Guide

API v2.0

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 RangeColorLabelMeaning
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

EndpointPurposeCall FrequencyLatency
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:

HeaderValue
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

POST /calculate High Frequency

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

FieldTypeRequiredDescriptionExample
agenumberNoAge in years35
sexstringNoBiological sex (M, F, Male, Female)"M"
rhrnumberNoResting Heart Rate (bpm)60
hrv_rmssdnumberNoHRV RMSSD (ms)50
vo2maxnumberNoVO2 Max (ml/kg/min)45
spo2_minnumberNoMinimum nocturnal SpO2 (%)96
steps_7d_avgnumberNoAverage daily steps (7-day). Also accepts steps8000
sleep_hours_7d_avgnumberNoAverage sleep hours (7-day). Also accepts sleep_hours7.5
sbpnumberNoSystolic Blood Pressure (mmHg)120
triglyceridesnumberNoTriglycerides (mg/dL)150
hdlnumberNoHDL Cholesterol (mg/dL)50
hba1cnumberNoHbA1c (%)5.5
smokingstringNoSmoking status code (see below)"never"
alcoholstringNoAlcohol consumption code (see below)"none"

Smoking Codes

CodeDescription
neverNever smoked
former_gt20Quit > 20 years ago
former_5to_lt20Quit 5–20 years ago
former_lt5Quit < 5 years ago
current_lt20Currently smoking < 20 cigs/day
current_20to40Currently smoking 20–40 cigs/day
current_ge40Currently smoking > 40 cigs/day

Alcohol Codes

CodeDescription
noneDon't drink
0_1_to_1_80.1 to 1.8 drinks/day
1_8_to_3_11.8 to 3.1 drinks/day
3_2_to_4_63.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

POST /partner/daily-refresh Once Per Day

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:

FieldTypeDefaultDescription
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

FieldTypeDescription
rankintegerRank by impact (1 = highest penalty)
metricstringHuman-readable metric name
current_valueanyCurrent value of the metric
score_penaltynumberEstimated score points lost
domainstring"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 NameAlso Accepts
steps_7d_avgsteps
sleep_hours_7d_avgsleep_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

StatusMeaningAction
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.