# Tredict API: Health Data This document covers reading and writing health-related data: body values (weight, body fat, resting heart rate), capacities (HRmax, FTP, FTPa), HRV, and sleep. It assumes that authentication is already set up (see `setup.md`), regardless of whether you use a Personal Access Token or an OAuth2 application. Health data in Tredict is organized as time series. Most endpoints return historical revisions, so you can see how a value changed over time, not just its current state. ## Required Scopes - `bodyvaluesRead` for reading body values, capacities, HRV, sleep, and zones. - `bodyvaluesWrite` for uploading body values, HRV, and sleep. Capacities and zones are read-only via the API. They are computed by Tredict from your training data and configured in the web interface. ## Body Values Body values cover weight, body composition, body height, and resting heart rate. Each measurement is a revision with its own timestamp, so the full history is preserved. ### Reading Body Values ``` GET https://www.tredict.com/api/oauth/v2/bodyvalues ``` **Response:** ```json { "bodyvalues": [ { "timestamp": 1745625600, "timezoneOffsetInSeconds": 7200, "weightInKilograms": 74.2, "restingHeartrate": 48, "bodyFatInPercent": 14.5 } ] } ``` Not every field is present in every revision. A morning weigh-in might only contain `weightInKilograms`, while a smart scale measurement might contain weight, body fat, body water, and muscle mass at once. ### Writing Body Values ``` POST https://www.tredict.com/api/oauth/v2/bodyvalues ``` **Body:** ```json { "bodyvalues": [ { "timestamp": 1745625600, "timezoneOffsetInSeconds": 7200, "weightInKilograms": 74.2, "restingHeartrate": 48 } ] } ``` **Mandatory fields:** `timestamp` (Unix seconds), `timezoneOffsetInSeconds`. **Optional fields:** `restingHeartrate`, `weightInKilograms`, `bodyHeightInCentimeter`, `bodyFatInPercent`, `bodyWaterInPercent`, `muscleMassInPercent`. You can post multiple revisions in one request by adding more entries to the `bodyvalues` array. ## Capacities Capacities are the threshold values Tredict uses to compute training zones and load: maximum heart rate, lactate threshold heart rate, FTP (functional threshold power, cycling), and FTPa (aerobic threshold power, mapped to running pace). ``` GET https://www.tredict.com/api/oauth/v2/capacity ``` **Parameters:** - `sportType` (optional): filter to one of `running`, `cycling`, `swimming`, `misc`. **Response shape:** ```json { "capacity": { "running": [ { "timestamp": 1735689600, "timezoneOffset": 3600, "hrMax": 188, "hrLth": 172, "ftpa": 256 } ], "cycling": [ ... ] } } ``` Each sport type has its own array of revisions. The newest revision is the currently active one. Tredict updates these automatically based on training data, but they can also be set manually in the web interface. `ftpa` for running is in seconds per kilometer (the pace at the aerobic threshold), consistent with the rest of the API's pace convention. ## Zones Zones are derived from capacities. They define the heart rate, pace, power, and cadence ranges for each training zone (e.g. zone 1 to zone 5). ``` GET https://www.tredict.com/api/oauth/v2/zones ``` **Parameters:** - `sportType` (optional): filter to one of `running`, `cycling`, `swimming`, `misc`. **Response shape:** Per sport type, four arrays of zone definitions (heart rate, pace, power, cadence). Each zone has `name`, `from`, `to`, and `intensity`. Each zone set carries a timestamp that serves as a revision key, so you can see how zones changed over time. Zones are read-only via the API. They are configured in Tredict's web interface or computed automatically from capacities. ## HRV (Heart Rate Variability) HRV in Tredict is stored as a daily night-time RMSSD value with a baseline. ### Reading HRV ``` GET https://www.tredict.com/api/oauth/v2/hrv ``` **Parameters:** - `startDate` (optional, ISO-8601, defaults to today): the newer end of the range. - `endDate` (optional, defaults to one year before `startDate`): the older end of the range. **Response shape:** ```json { "hrv": { "20260424": [42, 39], "20260425": [45, 40] } } ``` Keys are `YYYYMMDD` strings. Each value is a tuple `[RMSSD night, Baseline]`. ### Writing HRV ``` POST https://www.tredict.com/api/oauth/v2/hrv ``` **Body:** ```json { "hrv": [ { "timestamp": 1745625600, "timezoneOffsetInSeconds": 7200, "rmssd": 42 } ] } ``` **Mandatory fields:** `timestamp`, `timezoneOffsetInSeconds`, `rmssd` (in milliseconds, range 1 to 500). If an entry with the same `timestamp` already exists, it is overwritten. Use this to correct a previously uploaded value. ## Sleep ### Reading Sleep ``` GET https://www.tredict.com/api/oauth/v2/sleep ``` **Parameters:** - `startDate` (optional, defaults to today): the newer end of the range. - `endDate` (optional, defaults to one year before `startDate`): the older end of the range. **Response shape:** ```json { "sleep": { "20260424": [27000, 25800], "20260425": [29400, 26400] } } ``` Keys are `YYYYMMDD` strings. Each value is a tuple `[total sleep in seconds, Baseline]`. 27000 seconds is 7 hours 30 minutes. ### Writing Sleep ``` POST https://www.tredict.com/api/oauth/v2/sleep ``` **Body:** ```json { "sleep": [ { "startTimestamp": 1745604000, "endTimestamp": 1745632800, "timezoneOffsetInSeconds": 7200, "sleepDurationInSeconds": 27000 } ] } ``` **Mandatory fields:** `startTimestamp`, `endTimestamp` (both Unix seconds), `timezoneOffsetInSeconds`, `sleepDurationInSeconds` (1 to 86400). `sleepDurationInSeconds` is the actual time spent asleep, not the time in bed. So if you went to bed at 23:00 and got up at 07:00 (eight hours in bed) but were awake for 30 minutes during the night, send 27000 (7.5 hours), not 28800. If an entry with the same `startTimestamp` already exists, it is overwritten. ## Date and Time Conventions Health data uses a mix of timestamp formats. Be careful which one applies where: - **Request parameters** (`startDate`, `endDate`): ISO-8601 strings, e.g. `2026-04-26`. - **POST bodies** (writing values): Unix seconds in `timestamp`, `startTimestamp`, `endTimestamp`. - **GET response keys** (HRV, sleep): `YYYYMMDD` strings as object keys. - **GET response timestamps** (body values, capacities): Unix seconds in nested fields. Always send `timezoneOffsetInSeconds` along with timestamps when writing. Tredict uses it to attribute values to the correct calendar day. ## Behavior on Re-uploading For HRV and sleep, posting an entry with the same key (timestamp or startTimestamp) overwrites the existing one. This makes it safe to re-run a sync script: duplicates are silently merged, not stacked. For body values, each posted entry creates a new revision regardless of timestamp. If you want to correct a previous body value, this means you should be careful not to push the same measurement twice.