Fitnescity Health Developers
Public API documentation

Use Full API Integration—the default approach—to keep diagnostic testing search, customer identity, consent when required, ordering, questionnaires, scheduling, and results in your product. Start in Staging (Sandbox) for API Partner testing before switching hosts and credentials for live traffic.

Default test host
https://api-staging.engineeringfitnescity.com
Request access
Results

Results retrieval is polling-based and each result item includes result_units.

The results endpoint is designed for operational retrieval after Fitnescity Health completes downstream processing. It is scoped to the calling API Partner, exposes only allowlisted fields from the underlying result record, and returns a sibling result_units map for every result item.

What the endpoint returns

  • Customer details required for reconciliation: first_name, last_name, and email.
  • Fitnescity Health identifiers and status metadata: order_id, appointment_id, test_type, appointment_status, results_status, has_signed_form, followup_call_schedule_link, sent_date, and created_at.
  • has_signed_form is availability metadata, not the download itself. When it is true, call GET /v1/appointments/{appointmentId}/signed-form only when the member needs the temporary signed-form URL.
  • When present, followup_call_schedule_link is a member-facing physician follow-up call URL that your API Partner app can surface after results are ready.
  • For DEXA and DEXABMD records whose results_status is finalized, call GET /v1/appointments/{appointmentId}/report to download the underlying report document. It is usually a PDF, but a scan submitted as a photo comes back as an image, so branch on the returned content_type rather than assuming a PDF. The link is generated per request and expires after 15 minutes, so fetch it when the member asks for it rather than storing it. The document is prepared shortly after finalization, so a call made during preparation returns 503 with a Retry-After header; a 404 means no report is available.
  • A results object containing the allowlisted payload for that test record.
  • A sibling result_units object keyed exactly like results so your integration never has to infer units from raw location output.
Polling example
curl -X GET "https://api-staging.engineeringfitnescity.com/v1/results?order_id=3fa85f64-5717-4562-b3fc-2c963f66afa6&limit=25&offset=0" \
  -H "x-api-key: <staging-prefix>.<staging-secret>"

What “allowlisted results” means

The public API returns only the result fields approved for API Partner access in v1. That means the structure inside the results object can vary by test type, but it always stays within the approved public contract.

If your workflow depends on a result field that is not currently surfaced, treat that as a contract conversation rather than assuming it will appear later without notice.

Field availability can vary by test location reporting format. Blank values may be expected by design for certain test locations, including cases where a unit-sensitive source value cannot be mapped cleanly into the public API contract, and should not be interpreted as an ingestion failure on their own.

Use result_units as the source of truth for display and downstream mapping. Percent-style contract fields are returned in percent scale, for example 18.4 with unit % instead of a raw fractional value such as 0.184.

Some fields intentionally return null in result_units. That is expected for unitless scores, ratios, and categorical fields.

results + result_units example
{
  "results": {
    "body_fat_percentage": 18.4,
    "total_fat_mass": 27.8,
    "bmi": 24.2
  },
  "result_units": {
    "body_fat_percentage": "%",
    "total_fat_mass": "lbs",
    "bmi": null
  }
}
Test typeFields returned inside resultsUnits returned in result_units
DEXAresult_type, body_fat_percentage, body_fat_percentile, sex_assigned_at_birth, race, age_group, total_fat_mass, total_lean_mass, lean_mass_percentage, android_fat_percentage, gynoid_fat_percentage, android_fat, gynoid_fat, android_lean, android_lean_percentage, vat_fat_mass, vat_volume, total_body_weight, height, left_arm_fat_mass, left_arm_lean_mass, right_arm_fat_mass, right_arm_lean_mass, left_leg_fat_mass, left_leg_lean_mass, right_leg_fat_mass, right_leg_lean_mass, total_bone_mass, total_mass, bmd, z_score, bmd_percentile, gynoid_lean, bmi
null: result_type, sex_assigned_at_birth, race, age_group, z_score, bmi, body_fat_percentile, bmd_percentile
%: body_fat_percentage
STANDARD only %: lean_mass_percentage, android_fat_percentage, gynoid_fat_percentage, android_lean_percentage
lbs: total_fat_mass, android_fat, gynoid_fat, android_lean, vat_fat_mass, total_body_weight, left_arm_fat_mass, right_arm_fat_mass, left_leg_fat_mass, right_leg_fat_mass, total_bone_mass, total_mass, gynoid_lean
STANDARD only lbs: total_lean_mass, left_arm_lean_mass, right_arm_lean_mass, left_leg_lean_mass, right_leg_lean_mass
LIMITED only lbs: total_lean_and_bmc, left_arm_lean_and_bmc, right_arm_lean_and_bmc, left_leg_lean_and_bmc, right_leg_lean_and_bmc
LIMITED only g: left_arm_bmc, right_arm_bmc, left_leg_bmc, right_leg_bmc
in: height
in3: vat_volume
g/cm2: bmd
DEXABMDbmi, bmd, z_score, bmd_percentile, sex_assigned_at_birth, major_osteoporotic_fracture, hip_fracture, neck_* (area, bmc, bmd, t_score, z_score), neck_total_* (area, bmc, bmd, t_score, z_score), spine_l_one_* (L1 lumbar spine area, bmc, bmd, t_score, z_score), spine_l_two_* (L2 lumbar spine area, bmc, bmd, t_score, z_score), spine_l_three_* (L3 lumbar spine area, bmc, bmd, t_score, z_score), spine_l_four_* (L4 lumbar spine area, bmc, bmd, t_score, z_score), spine_total_* (total L1-L4 lumbar spine area, bmc, bmd, t_score, z_score)
null: sex_assigned_at_birth, bmi, z_score, bmd_percentile, *_t_score, *_z_score
%: major_osteoporotic_fracture, hip_fracture
cm2: *_area
g: *_bmc
g/cm2: bmd, *_bmd
RMRmeasured_rmr, estimated_ree, sex_assigned_at_birth, rer, bmi
kcal/day: measured_rmr, estimated_ree
null: sex_assigned_at_birth, rer, bmi
VO2 Maxmax_vo2, starting_vo2, starting_hr, aerobic_vo2, aerobic_hr, anaerobic_vo2, anaerobic_hr, max_hr, hrr_one_min, hrr_one_min_percentage, hrr_one_min_diff, hrr_two_min, hrr_two_min_percentage, hrr_two_min_diff, starting_mets, aerobic_mets, peak_mets, test_type, age_group, sex_assigned_at_birth, bmi
ml O2/kg/min: max_vo2, starting_vo2, aerobic_vo2, anaerobic_vo2
bpm: starting_hr, aerobic_hr, anaerobic_hr, max_hr, hrr_one_min, hrr_one_min_diff, hrr_two_min, hrr_two_min_diff
%: hrr_one_min_percentage, hrr_two_min_percentage
METs: starting_mets, aerobic_mets, peak_mets
null: test_type, age_group, sex_assigned_at_birth, bmi
BODPODbody_fat_percentage, total_fat_mass, lean_mass, lean_mass_percentage, sex_assigned_at_birth, body_fat_percentile, population_body_fat_avg, z_score, bmi
%: body_fat_percentage, lean_mass_percentage, population_body_fat_avg
lbs: total_fat_mass, lean_mass
null: sex_assigned_at_birth, body_fat_percentile, z_score, bmi
HYDROSTATICbody_fat_percentage, total_mass, fat_mass, fat_free_mass, fat_free_mass_percentage, body_density, lung_volume, water_temperature, body_fat_percentile, population_body_fat_avg, z_score, sex_assigned_at_birth, bmi
%: body_fat_percentage, fat_free_mass_percentage, population_body_fat_avg
lbs: total_mass, fat_mass, fat_free_mass
Kg/L: body_density
L: lung_volume
°C: water_temperature
null: sex_assigned_at_birth, body_fat_percentile, z_score, bmi
SECAbody_fat_percentage, fmi, sex_assigned_at_birth, fat_mass, fat_free_mass, fat_free_mass_percentage, body_water_percentage, ecw_tbw_ratio, vat, waist_circumference, bmi
%: body_fat_percentage, fat_free_mass_percentage, body_water_percentage, ecw_tbw_ratio
lbs: fat_mass, fat_free_mass
kg/m2: fmi
L: vat
in: waist_circumference
null: sex_assigned_at_birth, bmi
Calcium Scoretotal_score, percentile, upper_percentile, sex_assigned_at_birth, bmi, left_main, left_anterior_descending, left_circumflex, right_coronary_artery
null: total_score, percentile, upper_percentile, left_main, left_anterior_descending, left_circumflex, right_coronary_artery, sex_assigned_at_birth, bmi

DEXA STANDARD vs LIMITED unit coverage

DEXA responses always expose results.result_type so your mapping can distinguish the two public variants. Both variants include units through the sibling result_units object.

STANDARD includes the lean and fat percentage fields that return %, while shared mass fields remain in lbs, height remains in in, and vat_volume remains in in3.

LIMITED swaps in the combined-body fields. In that variant, *_bmc fields return g, while *_lean_and_bmc and total_lean_and_bmc return lbs.

DEXA field availability notes
  • Roughly 25 test locations may return the limited result format. In those responses, results.result_type is LIMITED and this field set is available: result_type, sex_assigned_at_birth, body_fat_percentage, body_fat_percentile, race, age_group, total_fat_mass, android_fat, gynoid_fat, android_lean, vat_fat_mass, vat_volume, total_body_weight, height, left_arm_fat_mass, right_arm_fat_mass, left_leg_fat_mass, right_leg_fat_mass, total_bone_mass, total_mass, bmd, z_score, bmd_percentile, gynoid_lean, bmi, total_lean_and_bmc, left_arm_bmc, left_arm_lean_and_bmc, right_arm_bmc, right_arm_lean_and_bmc, left_leg_bmc, left_leg_lean_and_bmc, right_leg_bmc, right_leg_lean_and_bmc
  • When DEXA returns LIMITED, result_units uses the same field keys, *_bmc fields return g, and *_lean_and_bmc plus total_lean_and_bmc return lbs.
  • Some test locations do not provide vat_fat_mass or vat_volume, so those fields may be blank.
  • A small number of test locations do not provide bmd or z_score. In those cases those fields are blank while the rest of the result remains populated.
  • About 5-8% of test locations provide combined arm and leg totals only. In those cases the combined arm total is placed in right_arm_* fields, the combined leg total is placed in right_leg_* fields, and the corresponding left-side fields are blank by design.
  • Some test locations do not provide arm or leg fat-mass values. In those cases left_arm_fat_mass, right_arm_fat_mass, left_leg_fat_mass, and right_leg_fat_mass may be blank while total_fat_mass remains populated.
  • A few test locations provide only gynoid_fat_percentage. In those cases gynoid_fat and gynoid_lean may be blank while gynoid_fat_percentage remains populated.
RMR field availability notes
  • Roughly 25% of test locations do not provide rer, so that field may be blank.
VO2 Max field availability notes
  • Some test locations do not provide post-exercise HRR metrics. In those cases hrr_one_min, hrr_one_min_percentage, hrr_one_min_diff, hrr_two_min, hrr_two_min_percentage, and hrr_two_min_diff may all be blank.
  • Some test locations also do not provide aerobic_vo2 or anaerobic_vo2, so those fields may be blank.