Concepts
Data model
CorrConnect returns one kind of record today, an activity summary. Every activity has the same required fields; the optional ones depend on where it came from.
Activities
{
"id": "act_0123456789abcdef0123456789abcdef",
"source": "tcx",
"activity_type": "run",
"started_at": "2026-10-12T06:31:05Z",
"duration_seconds": 2914.0,
"duration_basis": "recorded_lap_sum",
"distance_meters": 8012.4,
"distance_basis": "recorded_lap_sum",
"provenance": {"format": "TCX", "version": "2", "activity_index": 1},
"laps": [
{
"index": 1,
"started_at": "2026-10-12T06:31:05Z",
"duration_seconds": 2914.0,
"distance_meters": 8012.4,
"tracks": [{"index": 1, "point_count": 2914, "started_at": "2026-10-12T06:31:05Z", "ended_at": "2026-10-12T07:19:39Z"}]
}
],
"created_at": "2026-10-12T08:02:44+00:00"
}| Field | Always there | Notes |
|---|---|---|
id | Yes | act_ and 32 hex characters. Stable for the life of the record. |
source | Yes | Where it came from. See the table below. |
activity_type | Yes | run, ride, swim, walk, strength or other. |
started_at | Yes | ISO 8601 with a UTC offset. |
duration_seconds | Yes | A number; files can give fractions of a second. |
created_at | Yes | When CorrConnect stored it. Lists are ordered by this, newest first. |
distance_meters | No | Missing, or null, when the source has no distance. Never estimated. |
title | No | Missing or null when there isn't one. |
duration_basis, distance_basis | No | How the number was measured, for example recorded_lap_sum. |
provenance | No | The file format and the position of this activity in the file. |
laps | No | TCX and FIT: per-lap start, duration and distance. |
segments | No | GPX: per-segment point count, start, end and elapsed seconds. |
New optional fields and new values for source and the basis fields can appear without notice. Ignore what you don't recognize, and don't fill gaps: a missing distance means the source didn't record one.
Sources
| `source` | Comes from | What to expect |
|---|---|---|
manual_json | A summary the athlete imported in the portal | distance_meters and title are present, possibly null. No basis fields. |
gpx | A GPX 1.1 file | activity_type is always other (GPX has no sport). duration_basis is derived_. No distance. title from the track name. segments. |
tcx | A TCX v2 file | run, ride or other. Duration and distance are recorded_lap_sum. laps with track point counts. |
fit | A FIT activity file | Sport from the session: running, cycling, swimming, walking and strength training map to the five types; anything else is other. recorded_, and recorded_ when recorded. laps. |
One file can hold up to 20 activities (GPX tracks or TCX activities) or 20 FIT sessions; each becomes its own record. More about files in workout files.
What CorrConnect does not return
- GPS coordinates. Files are checked for valid positions, but points are never stored or returned.
- Sensor streams (heart rate, power, cadence by the second).
- The original file. There is no download endpoint.
- The athlete's email, name or CorrConnect account ID. You get the pairwise
subinstead.
IDs
| Prefix | What |
|---|---|
app_ | Your app's client_id |
act_ | Activity |
ccu_ | Athlete subject for your app (sub) |
evt_ | Webhook event; the same on every retry |
whs_ | Webhook subscription |
whd_ | One delivery of an event to one subscription |
req_ | Request ID on every response and error |
cca_, ccr_, ccc_ | Access token, refresh token, authorization code |
IDs are opaque. Compare them as whole strings and don't derive anything from the characters after the prefix.
Times
Every timestamp is ISO 8601 with a UTC offset, so parse them with a full ISO 8601 parser. CorrConnect's own times (created_at, event times) end in +00:00. Times read from a GPX, TCX or FIT file are converted to UTC and end in Z. A manual_json summary keeps the offset the athlete sent, for example 2026-09-22T07:15:00-04:00.