API access to Intervals.icu

I just had a look at your calendar and you only have weight and resting HR captured for 4th Feb. The 3rd of Feb has sleep, HRV SDNN, SpO2 etc as well. But no mood, fatigue etc…

I see you are using HealthFit. I don’t know if it uploads mood, fatigue etc… Probably not unless there is some corresponding setting in Apple Health.

Oh, I see. I actually thought I would be able to get those data from the system as I see them. If I understand it, they are calculated yet not available, correct?

1 Like

Ah! The fatigue in the wellness data is a subjective fatigue measure i.e. what did you feel like before training? It’s different to the calculated fatigue on the fitness chart.

You can get the chart numbers here: https://intervals.icu/api/athlete/2049151/activities.csv

That CSV includes lots of stuff including icu_fatigue and icu_fitness as after each activity.

I am going to improve this side of the API soon. I need to add an endpoint that gives you all the fitness info combined with wellness in JSON and/or CSV.

2 Likes

I’m experimenting with the workout endpoints today – as far as I can tell the current workflow for downloading a scheduled workout in an external format is something like:

  • GET /events for the athlete (say for the next week)
  • extra the workout_doc field from events identified as workouts
  • POST that same payload back up to /download-workout.mrc in order to get back an .mrc file.

Is the expectation for creating a workout similar? IE, POST to /workouts that same ‘workout_doc’ format? And if so, is there a spec of some sort for that format I could take a look at? (I’m sure I could reverse it, but it doesn’t hurt to ask. :slight_smile: )

Thats about right but I shouldn’t have added the download-workout endpoint to the public API just yet. I don’t want the workout_doc to be part of the public API. I need to make a version of that endpoint that accepts the id or the text for a workout instead. But if you pass in a workout_doc you have retrieved it will work.

The workout_doc is the parsed form of the workout text (the steps and whatnot) for a particular athlete (so all the % FTP and so on has been resolved to watts etc.). Currently I only have JavaScript code on the client to do this. I still need to sort this out server side. The server is Java so I need to create a separate little Node service using the same code as on the client to do this.

I am interested to know what you are up to :slight_smile: I can speed this up if needed!

What I’m driving toward is:

  1. load upcoming sufferfest outdoor workouts into intervals so I can track upcoming load/events
  2. pull scheduled workouts from intervals and transform them into the ‘wahooplan’ format
  3. load them onto my Wahoo head unit

IOW, reducing some of the pain listed here: Push workout to Wahoo There’s no getting around copy/pasting the foreign workout text and using a USB connection to load onto the Wahoo, but I figure everything should be automate-able.

Given a hand-created intervals workout I can get this done with the approach I outlined above. Fully automating the pipeline via API (as currently exposed) seems like it’ll require me to POST a new workout with workout_doc already in place, so it can be re-downloaded later as a .mrc file.

I agree that a more ideal workflow would be to upload the workout either as a standard format via convert-workout or just in a textual format that can be parsed server-side, then later pull a standard format back down by referencing a workout or event id.

Apologies if it’s already been asked, but is there a way of updating the FTP on an activity using the API? I have no problems exporting the IDs and looping through them (pulling the FTP data from another file based on the date), but I’m not 100% on what to use.

Edit - Tried a couple, but no joy. I thought it would have been the put on “/api/v1/athlete/{id}/events/{eventId}”, but I’m getting a server error. Do I need to send all the fields back?

No there isn’t but I have just added an endpoint, will deploy Sat AM (GMT+2):

PUT /api/v1/activity/{id}
{ icu_ftp: 300 }
1 Like

Ahh, nice one. Thanks. :slight_smile:

Hi! Is there a problem today? API don’t import ID activity from Strava.

Which endpoint are you calling?

/api/v1/athlete/{id}/activities.csv

thanks

It is working for me. Are some activities missing? Can you see the same on your calendar?

Solved, thanks. that was my problem.

You can now download planned workouts:

GET /api/v1/athlete/{id}/events/{eventId}/download{ext} Download a planned workout in .zwo, .mrc or .erg format.

1 Like

Some changes to the endpoints that create/update workouts on the calendar and in folders:

  • The workout description is now parsed. This means that workouts created or updated via the API have training load calculated and get “time in zones” and so on. This also applies to workouts synced from an external calendar.
  • You can now create/update workouts from zwo, mrc and erg files.

POST /api/v1/athlete/{id}/events

{
  "category": "WORKOUT",
  "start_date_local": "2021-04-29T00:00:00",
  "type": "Ride",
  "filename": "4x8m.zwo",
  "file_contents": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workout_file>..."
}

Response:

{
  "id": 610062,
  "icu_training_load": 116,
  ...
  "name": "4x8m VO2 Max",
  "description": "These are horribly nasty.\nCategory: Horrible\n\n- 20m 60% 90-100rpm\n\nMain set 4x\n- 8m 110%\n- 8m 50%\n\n- 10m 60%\n",
  ...
  "workout_doc": {
    "steps": [
      {
        "power": {"units": "%ftp", "value": 60},
        "cadence": {"end": 100, "start": 90, "units": "rpm"}, "duration": 1200
      }, ...
    ],
    "duration": 5640,
    "zoneTimes": [1920, 1800, 0, 0, 1920, 0, 0, 0],
    "hrZoneTimes": [1920, 1800, 0, 0, 1920, 0, 0, 0]
  },
  "icu_intensity": 86.04798
}
2 Likes

Is there an endpoint to post .fit files to?

For completed activities or planned workouts? You can upload completed activities:

POST /v1/athlete/{id}/activities

This accepts form data with ‘file’ containing the data as well as optional name and description fields. The file can be .fit, .gpx, .fit.gz, .gpx.gz or a zip file containing one or more of the same.

It won’t create duplicate activities (hash of file data is checked). It returns status code 201 if at least one activity was created, else 200. The body is an array of { icu_athlete_id, id } for each activity.

3 Likes

This is really interesting! Thanks for all the great work.
Having a play with this, is there a way to get just the last activity full data set instead of all of them, for the activities.csv endpoint?
Cheers!

Tx. You can do:

GET /api/v1/athlete/{id}/activities?oldest=2019-07-22T16:18:49&newest=2019-08-23T12:18:24

To list activities in JSON format between 2 local dates in local date order.

GET /api/v1/activity/{id} to get a single activity in JSON format
GET /api/v1/activity/{id}/file to get the raw file for a single activity (if available)

You can also upload new activities:

POST /api/v1/athlete/{id}/activities

Accepts form data with ‘file’ being the fit, gpx or tax file. Also optional name and description. De-dups uploaded files on content hash.

1 Like