Writing 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

Terra allows you to write data back to a user's account, wherever supported by the respective Provider.

Writing Planned Workouts

Overview

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

Writing Planned Workouts

Supported providers

Currently supported providers are:

  • Garmin

  • Hammerhead

  • Coros

  • TodaysPlan

See the Supported integrations page for a full list of supported data types per Provider

Usage

In order to write a planned workout to the user's device, you may use the following endpoint

post

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)

Header parameters
dev-idstringRequired

your developer ID

Example: testingTerra
x-api-keystringRequired

your API key

Example: OtHJok60oQmT8zhnUWc4SWBJI7ztPTs88C0gOsJJ
Body
Responses
201
Returned when activity was successfully created on the provider
application/json
post
POST /v2/plannedWorkout HTTP/1.1
Host: api.tryterra.co
dev-id: text
x-api-key: text
Content-Type: application/json
Accept: */*
Content-Length: 523

{
  "data": [
    {
      "steps": {},
      "metadata": {
        "estimated_energy_kj": 1,
        "estimated_speed_meters_per_second": 1,
        "estimated_elevation_gain_meters": 1,
        "estimated_tss": 1,
        "estimated_calories": 1,
        "created_date": "2022-11-23T09:00:00.000000+02:00",
        "planned_date": "2022-11-24T09:00:00.000000+02:00",
        "type": "IN_VEHICLE",
        "id": "text",
        "estimated_duration_seconds": 1,
        "estimated_pace_minutes_per_kilometer": 1,
        "provider": "text",
        "estimated_tscore": 1,
        "description": "text",
        "name": "text",
        "estimated_distance_meters": 1,
        "estimated_if": 1,
        "pool_length_meters": 1
      }
    }
  ]
}
{
  "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",
    "active": true
  },
  "log_ids": [
    "text"
  ],
  "message": "Nutrition successfully logged"
}

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 REST API Endpointsendpoint, or to delete them using the REST API Endpoints

Examples

Aerobic fitness test

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
            }
        }
    ]
}

Last updated

Was this helpful?