---
title: "What connected apps have put on the calendar"
method: GET
path: "/schedule/apps"
tags: ["Training"]
---

# What connected apps have put on the calendar

`GET /schedule/apps`

## Request

- Base URL: `https://bodylab.lol/api/v1`
- URL: `https://bodylab.lol/api/v1/schedule/apps`
- Auth: HTTP bearer

One entry per app that has something standing on the calendar — a session not withdrawn, or an event — whether or not it is still connected. An app that scheduled nothing, or whose every session has since been withdrawn, is absent rather than empty. The athlete's own sessions and events are never here: this answers what an app did, not what the calendar holds.

## Headers

- `X-Client-Platform` string
- `X-Client-Version` string

## Response `200`

OK

- object
  - `apps` object[], required
    - `clientId` string, required: The app's OAuth client id: what its rows' `scheduledBy` holds, and what `withdrawAppSchedule` takes.
    - `name` string, nullable, required: What the app calls itself, as on `GET /me/connected-apps`; unverified unless `publisher` is set. Null for an app whose registration Body Lab no longer holds.
    - `publisher` string, nullable, required: The website the app's details were published on, which vouches for the name. Null for an app that registered itself.
    - `connected` boolean, required: Whether the athlete still allows this app. False after disconnecting it; what it scheduled stays until withdrawn here.
    - `commitments` object[], required: Sessions this app put on the calendar that are still standing, past and upcoming, by date. Never a withdrawn one.
      - `id` string, required: Opaque identifier.
      - `kind` string, required: session: a session described by its sport, duration and intensity. strength_routine: a strength routine, whose exercises `GET /strength-routines` returns. Withdrawn the same way, either kind. Known values: session, strength_routine. Treat unknown values as "other".
      - `forDate` string, date, required: The day it happens, on the athlete's own calendar.
      - `name` string, required: What the athlete called it.
      - `sport` string, required: Sport, from the engine's vocabulary (packages/engine/src/sports.ts), e.g. road_biking, running, hiking, strength_training. Known values: road_biking, running, hiking, strength_training, other. Treat unknown values as "other".
      - `durationS` integer, required: How long the athlete expects it to take.
      - `intensity` string, required: How hard the athlete says this session usually is. easy: steady aerobic, and the week may still put a hard day beside it. mixed: it has efforts in it. hard: it is the day's hard session. mixed and hard both make the day a hard one, which is what stops the engine prescribing a second hard day next to it. Known values: easy, mixed, hard. Treat unknown values as "other".
      - `withdrawnAt` string, date-time, nullable, required: An instant: ISO-8601 with offset, e.g. 2026-09-13T06:30:00Z.
      - `scheduledBy` string, nullable, required: The connected app that put this on the calendar, as its OAuth client id — the `clientId` that `GET /schedule/apps` names and `POST /schedule/apps/withdraw` takes. Null when the athlete entered it themselves, in any of their own apps.
      - `createdAt` string, date-time, required: An instant: ISO-8601 with offset, e.g. 2026-09-13T06:30:00Z.
    - `events` object[], required: Races and goals this app put on the calendar, by date. All of them: an event is removed outright rather than withdrawn, so one that exists is one that stands.
      - `id` string, required: Opaque identifier.
      - `name` string, required
      - `eventDate` string, date, required: A day on the athlete's own calendar: YYYY-MM-DD, no time zone.
      - `sport` string, required: Sport, from the engine's vocabulary (packages/engine/src/sports.ts), e.g. road_biking, running, hiking, strength_training. Known values: road_biking, running, hiking, strength_training, other. Treat unknown values as "other".
      - `priority` string, required: What Body Lab does with the event. A: the plan is built around it — preparation phases in the run-up, volume tapering into it, and a protected recovery window after. B and C move no volume, and the two behave identically. Any event, at any priority, makes its own date an event day, when nothing is prescribed, and an upcoming one tilts which sport a nearby day picks. Known values: A, B, C. Treat unknown values as "other".
      - `distanceM` number, nullable, required
      - `durationS` number, nullable, required
      - `notes` string, required
      - `daysUntil` integer, required: Negative once the event has passed. Computed server-side from the athlete's own time zone, never the server's.
      - `scheduledBy` string, nullable, required: The connected app that put this on the calendar, as its OAuth client id — the `clientId` that `GET /schedule/apps` names and `POST /schedule/apps/withdraw` takes. Null when the athlete entered it themselves, in any of their own apps.
      - `createdAt` string, date-time, required: An instant: ISO-8601 with offset, e.g. 2026-09-13T06:30:00Z.
      - `updatedAt` string, date-time, required: An instant: ISO-8601 with offset, e.g. 2026-09-13T06:30:00Z.

## Other responses

- `401`: Error: UNAUTHORIZED.

---

[API](https://skmtc.dev/bodylab/apis/body-lab-api.md) · [All operations](https://skmtc.dev/bodylab/apis/body-lab-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bodylab/apis/body-lab-api/revisions/544c201eaf88?raw)
