Write data
Learn how to write data back to providers, and create a bi-directional data stream between your app and the various integrations you connect to
Last updated
Was this helpful?
Learn how to write data back to providers, and create a bi-directional data stream between your app and the various integrations you connect to
Last updated
Was this helpful?
Terra allows you to write data back to a user's account, wherever supported by the respective .
Writing planned workouts allows you to create a workout plan for the user (such as those commonly used with Zwift)
This will typically look like the following example:
Planned workouts consist of a series of steps. Each step has:
Completion criteria (called duration for all intents and purposes). For example:
distance (keep going until you cover 500m),
energy expenditure (keep going until you burn 200 kcal)
heart rate threshold (keep going until your heart rate reaches above 150 bpm)
etc..
One or more targets to be maintained
heart rate (maintain heart rate between certain bounds)
speed (maintain speed between certain bounds)
grade (inclination above a certain threshold)
etc...
An associated intensity label
Warmup
Active
Cooldown
etc..
An exercise type
Running
Cycling
Deadlifting
etc...
A series of sub-steps
These modalities allow any workout to be described in a series of defined steps for each of its segments.
Once written, a planned workout will be available in the user's library of workouts on the respective platform, and the user will then be able to follow the workout step by step on their wearable device
Currently supported providers are:
Garmin
Hammerhead
Coros
TodaysPlan
In order to write a planned workout to the user's device, you may use the following endpoint
Used to post workout plans users can follow on their wearable. This can be stregnth workouts (sets, reps, weight lifted) or cardio workouts (warmup, intervals of different intensities, cooldown etc)
/plannedWorkout
your developer ID
testingTerra
your API key
OtHJok60oQmT8zhnUWc4SWBJI7ztPTs88C0gOsJJ
PlannedWorkout entry to post to data provider
curl -L \
--request POST \
--url 'https://api.tryterra.co/v2/plannedWorkout' \
--header 'x-api-key: text' \
--header 'dev-id: text' \
--header 'Content-Type: application/json' \
--data '{"data":[{"steps":{},"metadata":{"created_date":"2022-11-23T09:00:00.000000+02:00","planned_date":"2022-11-24T09:00:00.000000+02:00","id":null,"type":"IN_VEHICLE"}}]}'
{
"user": {
"reference_id": "[email protected]",
"last_webhook_update": "2022-12-12T10:00:00.000000+00:00",
"scopes": "activity:read,sleep:read",
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"provider": "FITBIT"
},
"message": "Nutrition successfully logged",
"log_ids": [
"text"
]
}
Returned when activity was successfully created on the provider
The aerobic fitness test begins with a 5 minute warm-up.
After warming up, the intensity will ramp up over the duration of 5 minutes, reaching a 91% max HR intensity.
Once you are done with the all out effort, you will spend 2 minutes in a recovery step, before spending 5 minutes cooling down
{
"data": [
{
"steps": [
{
"type": 1,
"order": 0,
"description": "Warm Up BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Warm Up",
"durations": [
{
"duration_type": 0,
"seconds": 300
}
],
"targets": [
{
"target_type": 13,
"hr_percentage_high": 70.0,
"hr_percentage_low": 60.0,
"hr_percentage": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Warm Up RAMP_UP",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Ramp Up 1",
"durations": [
{
"duration_type": 0,
"seconds": 60
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 79.5,
"hr_percentage_low": 79.5,
"hr_percentage": 79.5
},
{
"target_type": 13,
"hr_percentage_high": 70.0,
"hr_percentage_low": 70.0,
"hr_percentage": 70.0
},
{
"target_type": 15,
"power_percentage_high": 65,
"power_percentage_low": 65,
"power_percentage": 65
},
{
"target_type": 3,
"cadence_high": 95.0,
"cadence_low": 85.0,
"cadence": null
}
]
},
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Ramp Up 2",
"durations": [
{
"duration_type": 0,
"seconds": 60
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 85.8,
"hr_percentage_low": 85.8,
"hr_percentage": 85.8
},
{
"target_type": 13,
"hr_percentage_high": 76.0,
"hr_percentage_low": 76.0,
"hr_percentage": 76.0
},
{
"target_type": 15,
"power_percentage_high": 75,
"power_percentage_low": 75,
"power_percentage": 75
},
{
"target_type": 3,
"cadence_high": 95.0,
"cadence_low": 85.0,
"cadence": null
}
]
},
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Ramp Up 3",
"durations": [
{
"duration_type": 0,
"seconds": 60
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 91.6,
"hr_percentage_low": 91.6,
"hr_percentage": 91.6
},
{
"target_type": 13,
"hr_percentage_high": 82.0,
"hr_percentage_low": 82.0,
"hr_percentage": 82.0
},
{
"target_type": 15,
"power_percentage_high": 85,
"power_percentage_low": 85,
"power_percentage": 85
},
{
"target_type": 3,
"cadence_high": 95.0,
"cadence_low": 85.0,
"cadence": null
}
]
},
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Ramp Up 4",
"durations": [
{
"duration_type": 0,
"seconds": 60
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 96.7,
"hr_percentage_low": 96.7,
"hr_percentage": 96.7
},
{
"target_type": 13,
"hr_percentage_high": 87.0,
"hr_percentage_low": 87.0,
"hr_percentage": 87.0
},
{
"target_type": 15,
"power_percentage_high": 95,
"power_percentage_low": 95,
"power_percentage": 95
},
{
"target_type": 3,
"cadence_high": 95.0,
"cadence_low": 85.0,
"cadence": null
}
]
},
{
"type": 0,
"order": 0,
"intensity": 6,
"description": "Ramp Up 5",
"durations": [
{
"duration_type": 0,
"seconds": 60
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 101.4,
"hr_percentage_low": 101.4,
"hr_percentage": 101.4
},
{
"target_type": 13,
"hr_percentage_high": 91.0,
"hr_percentage_low": 91.0,
"hr_percentage": 91.0
},
{
"target_type": 15,
"power_percentage_high": 105,
"power_percentage_low": 105,
"power_percentage": 105
},
{
"target_type": 3,
"cadence_high": 95.0,
"cadence_low": 85.0,
"cadence": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Recovery BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Recovery",
"durations": [
{
"duration_type": 0,
"seconds": 120
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 76.0,
"hr_percentage_low": 69.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": 67.0,
"hr_percentage_low": 60.0,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": 60,
"power_percentage_low": 50,
"power_percentage": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Main Session BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 12,
"description": "Sprint",
"durations": [
{
"duration_type": 0,
"seconds": 8
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": null,
"hr_percentage_low": 106.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": null,
"hr_percentage_low": 98.5,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": null,
"power_percentage_low": 200,
"power_percentage": null
},
{
"target_type": 3,
"cadence_high": 120.0,
"cadence_low": 100.0,
"cadence": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Recovery BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Recovery",
"durations": [
{
"duration_type": 0,
"seconds": 180
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 73.0,
"hr_percentage_low": 65.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": 63.0,
"hr_percentage_low": 57.0,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": 55,
"power_percentage_low": 45,
"power_percentage": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Main Session BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 12,
"description": "Sprint",
"durations": [
{
"duration_type": 0,
"seconds": 8
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": null,
"hr_percentage_low": 106.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": null,
"hr_percentage_low": 98.5,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": null,
"power_percentage_low": 200,
"power_percentage": null
},
{
"target_type": 3,
"cadence_high": 120.0,
"cadence_low": 100.0,
"cadence": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Recovery BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Recovery",
"durations": [
{
"duration_type": 0,
"seconds": 300
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 73.0,
"hr_percentage_low": 65.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": 63.0,
"hr_percentage_low": 57.0,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": 55,
"power_percentage_low": 45,
"power_percentage": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Main Session BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Aerobic Test",
"durations": [
{
"duration_type": 0,
"seconds": 480
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": null,
"hr_percentage_low": 106.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": null,
"hr_percentage_low": 98.5,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": null,
"power_percentage_low": 98,
"power_percentage": null
},
{
"target_type": 3,
"cadence_high": 110.0,
"cadence_low": 90.0,
"cadence": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Recovery BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Recovery",
"durations": [
{
"duration_type": 0,
"seconds": 120
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 73.0,
"hr_percentage_low": 65.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": 63.0,
"hr_percentage_low": 57.0,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": 55,
"power_percentage_low": 45,
"power_percentage": null
}
]
}
]
},
{
"type": 1,
"order": 0,
"description": "Cool Down BASIC",
"durations": [
{
"duration_type": 9,
"reps": 1
}
],
"steps": [
{
"type": 0,
"order": 0,
"intensity": 5,
"description": "Cool Down",
"durations": [
{
"duration_type": 0,
"seconds": 300
}
],
"targets": [
{
"target_type": 12,
"hr_percentage_high": 73.0,
"hr_percentage_low": 69.0,
"hr_percentage": null
},
{
"target_type": 13,
"hr_percentage_high": 63.0,
"hr_percentage_low": 60.0,
"hr_percentage": null
},
{
"target_type": 15,
"power_percentage_high": 55,
"power_percentage_low": 50,
"power_percentage": null
}
]
}
]
}
],
"metadata": {
"type": 1,
"name": "Aerobic Fitness Test",
"description": "The aerobic fitness test begins with a warm-up. After warming up, you will be required to complete two maximal sprints. Once you are done with the sprints, you will have to undergo a 9-minute all-out test. During the test, it is important to pace yourself and give your best effort, sustaining it for the entire duration of 8 minutes.",
"provider": "COROS",
"planned_date": "2025-01-29",
"estimated_duration_seconds": 2100
}
}
]
}
See the https://github.com/tryterra/gitbook-docs/blob/master/health-and-fitness-api/broken-reference/README.md page for a full list of supported data types per
The response will include log_ids
which will be a list of the identifiers for the uploaded workout plans. You may use those identifiers to identify the workout plan later on in the GET
endpoint, or to delete them using the DELETE