- Brand
- Lion Lift
- Category
- Health & Wellness
- Primary Subcategory
- Endurance Sport Training Planners
Integration details
Description
Use your Lion Lift workout history to plan runs, pool swims, bike rides, and lifts; review progress across sports; compare planned and completed sessions; and create training reports.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Endurance Sport Training Planners
- Secondary Subcategories
- None listed
- Brand
- Lion Lift
- Access
- Account required
- First tracked
- 2026-10-20
- Tool count
- 13
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Lion Lift
Get updates when Lion Lift’s Discoverability Score or category rank changes.
Competing in ChatGPT Endurance Sport Training Planners
View Category13 tools agents can invoke
General-purpose read: query `collection` with any combination of a date range and arbitrary field filters. Works for one record (limit=1) or many — no separate bulk tool needed, and no field/filter is hardcoded — any field that exists (see list_fields) can be filtered, ordered, or projected on. start_date / end_date: ISO 8601 date or datetime strings (e.g. "2026-09-01"), applied to whichever field this collection actually uses for its date (resolved automatically per collection). A bare date with no time component is inclusive on both ends — start_date="2026-09-17", end_date="2026-09-17" means the whole day, not a zero-width instant at midnight. Records' dates are stored in raw UTC (not local time), so a workout logged late evening in a US timezone can appear one calendar day later than the user experienced it — when in doubt near a day boundary, widen the range by a day on each side rather than trust an exact single-day match. filters: a list of {"field": ..., "op": "==|!=|<|<=|>|>=|in|not-in| array-contains|array-contains-any", "value": ...} for anything beyond the date range (e.g. status, muscleGroup) — as many as needed, on any field. select_fields: return only these top-level fields per record (plus "_id") instead of the whole document — use this to fit more records under the response size cap when you don't need every field. start_after_id: pass the previous call's `next_start_after_id` to page past `limit` for a query that has more matching records than fit in one call or under the response size cap. Results are capped at config.MAX_RECORDS_PER_FETCH regardless of the requested limit — this is a personal read tool, not a bulk export pipe. The whole response is also subject to the server's ResponseLimiting middleware (config.MAX_RESPONSE_BYTES); an oversized response comes back truncated with a note rather than ballooning.
fetch_records
The connected user's own top-level profile: sex, stated training experience, and name. This is the one tool that reads the `users/{uid}` document itself rather than one of its subcollections — every other tool here is subcollection-scoped (lifts/run/bike/swim/ etc.) and can't reach these fields at all. There is no age, height, or weight field here, or anywhere else in this app right now. Never guess a value for any of these — if one would materially change an analysis (e.g. interpreting a heart-rate zone, or judging whether a load increase is reasonable for this person), ask the user directly instead of proceeding as if it's known. Any field below can also simply be unset for a given user; treat a missing field as "not provided," not an error — fall back to asking the user directly (e.g. for sex) if it's actually needed.
get_profile
Fetch one exact document by id. Pass select_fields to get back only those top-level fields if the full document might be large.
get_record
List cycling workouts this server has created for the user via schedule_bike_workout, most-recently-created first. status: optional filter — "pending" (not yet synced to Apple Fitness), "synced" (currently live on the user's Watch), or "deleted" (removed from Apple Fitness, kept here so the user can re-sync it later). Omit to see all of them. start_date / end_date: ISO 8601 date or datetime strings (e.g. "2026-09-01"), filtered against scheduledFor (when the ride is/was intended to happen), not when it was created. A bare date is inclusive on both ends, same convention as fetch_records. limit: capped at config.MAX_RECORDS_PER_FETCH regardless of what's requested, same as fetch_records. If you see a "pending" one that's days old, it likely just means the user hasn't opened Lion Lift and tapped Sync yet — mention that rather than assuming something went wrong.
list_bike_workouts
List every subcollection that actually exists under this account right now (e.g. "lifts", "run", "bike", "swim", "core", plus anything else present) — discovered live from Firestore, not a hardcoded guess.
list_collections
Sample a handful of real documents from `collection` and return every field name observed, each with one example value — Firestore has no fixed schema, so this is live discovery, not a spec. Use this before fetch_records if you're not sure what fields/dates a collection has.
list_fields
The app's own exercise name catalog (from Views/Constants/LiftsCatalog.swift, copied verbatim). Call this before schedule_lift so exercise names match what the app and its own autocomplete already use, instead of inventing new ones. Not enforced server-side — the app itself treats exercise names as free text — this is just here to keep things consistent.
list_known_exercises
List interval run workouts this server has created for the user via schedule_interval_run, most-recently-created first. status: optional filter — "pending" (not yet synced to Apple Fitness), "synced" (currently live on the user's Watch), or "deleted" (removed from Apple Fitness, kept here so the user can re-sync it later). Omit to see all of them. start_date / end_date: ISO 8601 date or datetime strings (e.g. "2026-09-01"), filtered against scheduledFor (when the run is/was intended to happen), not when it was created. A bare date is inclusive on both ends, same convention as fetch_records — end_date="2026-09-17" means through the end of that day. limit: capped at config.MAX_RECORDS_PER_FETCH regardless of what's requested, same as fetch_records. If you see a "pending" one that's days old, it likely just means the user hasn't opened Lion Lift and tapped Sync yet — mention that rather than assuming something went wrong.
list_run_workouts
List pool swim workouts this server has created for the user via schedule_pool_swim_workout, most-recently-created first. status: optional filter — "pending" (not yet synced to Apple Fitness), "synced" (currently live on the user's Watch), or "deleted" (removed from Apple Fitness, kept here so the user can re-sync it later). Omit to see all of them. start_date / end_date: ISO 8601 date or datetime strings (e.g. "2026-09-01"), filtered against scheduledFor (when the swim is/was intended to happen), not when it was created. A bare date is inclusive on both ends, same convention as fetch_records. limit: capped at config.MAX_RECORDS_PER_FETCH regardless of what's requested, same as fetch_records. If you see a "pending" one that's days old, it likely just means the user hasn't opened Lion Lift and tapped Sync yet — mention that rather than assuming something went wrong.
list_swim_workouts
Create a structured cycling workout — warmup, repeatable work/ recovery blocks, cooldown, each step with an optional heart-rate/ speed/power/cadence alert. Mirrors Apple's own WorkoutKit object model for cycling. IMPORTANT — confirm before calling: describe the full workout back to the user in plain language (warmup, every block's work/recovery and iteration count, any target speed/heart rate/power/etc., cooldown, and the scheduled date/time) and get their explicit confirmation first. This writes to their real account immediately and irreversibly from this server's own perspective — there's no "undo" tool. This does NOT put the workout on Apple Fitness/the Watch by itself — it only creates a pending record. WorkoutKit scheduling is a local, on-device operation this server has no way to perform remotely, so the user still has to open Lion Lift and tap "Sync" themselves (Workouts tab → Bike → Sync Workouts). Tell them that's the next step. There's no indoor/outdoor parameter here — the user picks trainer vs. road when they actually start the workout on the Watch, not at scheduling time. display_name: come up with a short, specific, memorable title based on what this workout actually is (e.g. "Sweet Spot Intervals", "Hill Repeats") — not a generic label like "Bike Workout" every time. Shown as this workout's title on the Watch/Fitness app and in Lion Lift's own Sync Workouts list, where several of these can be listed side by side. scheduled_for: "YYYY-MM-DDTHH:MM", 24-hour, the user's local time — when they intend to do this ride. Confirm "today"/"tomorrow" explicitly rather than assuming a timezone, same as schedule_lift. blocks: at least one BikeIntervalBlockInput. Each has: - iterations (int, default 1): how many times the work/recovery pair repeats. - work (required) / recovery (optional): each a BikeStepInput — see below. warmup / cooldown: optional single BikeStepInputs (no iteration count). A BikeStepInput is: {goal, alert?, display_name?}. - display_name: optional label for that one step, e.g. "Climb Repeat". - goal (a BikeGoalInput): {type, ...}. type is one of: "open" — no fields needed, the user advances it manually. "time" — needs seconds (float). "distance" — needs miles (float). "energy" — needs kilocalories (float). - alert (a BikeAlertInput, optional): {type, ...}. type is one of: "heartRateZone" — needs zone (int, e.g. 1-5). "heartRateRange" — needs bpm_low, bpm_high. "speedThreshold" — needs mph, optional metric ("average"/"current", default "average"). "speedRange" — needs mph_low, mph_high, optional metric. "powerZone" — needs zone (int). "powerRange" — needs watts_low, watts_high. "powerThreshold" — needs watts. "cadenceRange" — needs rpm_low, rpm_high (pedal RPM). "cadenceThreshold" — needs rpm (pedal RPM). Example — "5x5min hill repeats at 250-280W, 3 min easy spin recovery, with a 10 minute warmup and 10 minute cooldown": warmup = {"goal": {"type": "time", "seconds": 600}} blocks = [{ "iterations": 5, "work": { "goal": {"type": "time", "seconds": 300}, "alert": {"type": "powerRange", "watts_low": 250, "watts_high": 280}, "display_name": "Climb Repeat", }, "recovery": {"goal": {"type": "time", "seconds": 180}, "display_name": "Spin Recovery"}, }] cooldown = {"goal": {"type": "time", "seconds": 600}}
schedule_bike_workout
Create a structured interval running workout — warmup, repeatable work/recovery blocks, cooldown, each step with an optional pace/heart- rate/power/cadence alert. Mirrors Apple's own WorkoutKit object model field-for-field (CustomWorkout/WorkoutStep/IntervalBlock/WorkoutGoal/ WorkoutAlert). IMPORTANT — confirm before calling: describe the full workout back to the user in plain language (warmup, every block's work/recovery and iteration count, any target pace/heart rate/etc., cooldown, indoor vs outdoor, and the scheduled date/time) and get their explicit confirmation first. This writes to their real account immediately and irreversibly from this server's own perspective — there's no "undo" tool. This does NOT put the workout on Apple Fitness/the Watch by itself — it only creates a pending record. WorkoutKit scheduling is a local, on-device operation this server has no way to perform remotely, so the user still has to open Lion Lift and tap "Sync" themselves (Workouts tab → Run → Sync Workouts). Tell them that's the next step. display_name: come up with a short, specific, memorable title based on what this workout actually is — e.g. "50m Sprint Repeats", "Tempo Ladder", "5x800 Negative Split" — not a generic label like "Interval Run" every time. Shown as this workout's title on the Watch/Fitness app and in Lion Lift's own Sync Workouts list, where several of these can be listed side by side, so it needs to read as distinct from the user's other workouts at a glance, not just descriptive in isolation. scheduled_for: "YYYY-MM-DDTHH:MM", 24-hour, the user's local time — when they intend to do this run. Confirm "today"/"tomorrow" explicitly rather than assuming a timezone, same as schedule_lift. location: "outdoor" (default, GPS-based — required for any pace/speed alert) or "indoor" (treadmill — pace alerts aren't meaningful without GPS; use a heart-rate or cadence alert instead for an indoor workout). blocks: at least one IntervalBlockInput. Each has: - iterations (int, default 1): how many times the work/recovery pair repeats. - work (required) / recovery (optional): each a StepInput — see below. warmup / cooldown: optional single StepInputs (no iteration count). A StepInput is: {goal, alert?, display_name?}. - display_name: optional label for that one step, e.g. "800m Repeat". - goal (a GoalInput): {type, ...}. type is one of: "open" — no fields needed, the user advances it manually. "time" — needs seconds (float). "distance" — needs miles (float). "energy" — needs kilocalories (float). - alert (an AlertInput, optional): {type, ...}. type is one of: "heartRateZone" — needs zone (int, e.g. 1-5). "heartRateRange" — needs bpm_low, bpm_high. "paceThreshold" — needs pace_sec_per_mile, optional metric ("average"/"current", default "average"). "paceRange" — needs pace_sec_per_mile_low, pace_sec_per_mile_high (lower = faster), optional metric. "powerZone" — needs zone (int). "powerRange" — needs watts_low, watts_high. "powerThreshold" — needs watts. "cadenceRange" — needs spm_low, spm_high (steps/min). "cadenceThreshold" — needs spm (steps/min). Example — "5x800m at 6:30-7:00/mile pace, 2 min jog recovery, with a 10 minute warmup and 5 minute cooldown": warmup = {"goal": {"type": "time", "seconds": 600}} blocks = [{ "iterations": 5, "work": { "goal": {"type": "distance", "miles": 0.5}, "alert": {"type": "paceRange", "pace_sec_per_mile_low": 390, "pace_sec_per_mile_high": 420}, "display_name": "800m Repeat", }, "recovery": {"goal": {"type": "time", "seconds": 120}, "display_name": "Jog Recovery"}, }] cooldown = {"goal": {"type": "time", "seconds": 300}}
schedule_interval_run
Schedule a new lift workout. This is the only write this server can do, deliberately narrow in scope — create-a-scheduled-lift only, never update/complete/delete. Mirrors exactly what the app itself writes when scheduling a workout (ManualWorkoutEntryView.saveWorkout() / LiftCompletionService.complete()), so a workout scheduled here behaves identically to one scheduled from the app — shows up in today's-workouts queries, syncs to the watch on its next check-in, etc. IMPORTANT — confirm before calling: always show the user the exact workout you're about to schedule (date, every exercise, every set's weight/reps, and notes if any) and get their explicit confirmation first. This tool writes to their real, live workout schedule immediately and irreversibly from its own perspective (there's no "undo" tool) — never call it speculatively or as part of just thinking out loud with the user. scheduled_date: a plain calendar date, "YYYY-MM-DD" (e.g. "2026-09-20") — not a datetime, since scheduling is a whole-day concept. Confirm "today" with the user rather than assuming a timezone if the date is ambiguous (e.g. requested near midnight) — this server has no configured local timezone to resolve that for you. Every other date-shaped field the app relies on (the display string, date_ymd, date_ts, weekId) is derived from this single input, matching exactly what the app's own code computes for it — status is always "scheduled" and created_at is always "now," neither is a parameter. lifts: exercise name + sets (weight in lbs, reps) per exercise — call list_known_exercises() first for real exercise names instead of inventing new ones. Muscle group(s) are auto-classified from these exercise names, exactly like the app itself now does — there's no muscle_group parameter to set. notes: optional, defaults to empty. Once this lift is actually completed, its `lifts` field gets overwritten with the real final sets — the planned weight/reps you pass here stop being visible there. A frozen copy of what you scheduled survives separately in `original_lift_plan` (set automatically, nothing to pass for it), so a completed lift can later be compared planned-vs-actual the same way it works for scheduled runs/swims/rides.
schedule_lift
Create a structured POOL swimming workout — warmup, repeatable work/recovery blocks, cooldown, each step with an optional heart-rate/ power/cadence alert and an optional stroke-type label — mirroring Apple's own WorkoutKit object model for pool swimming specifically (open-water swimming isn't supported by this tool). IMPORTANT — confirm before calling: describe the full workout back to the user in plain language (warmup, every block's work/recovery and iteration count, any stroke types, any target heart rate/etc., cooldown, and the scheduled date/time) and get their explicit confirmation first. This writes to their real account immediately and irreversibly from this server's own perspective — there's no "undo" tool. This does NOT put the workout on Apple Fitness/the Watch by itself — it only creates a pending record. WorkoutKit scheduling is a local, on-device operation this server has no way to perform remotely, so the user still has to open Lion Lift and tap "Sync" themselves (Workouts tab → Swim → Sync Workouts). Tell them that's the next step. Pool length and pool-vs-open-water are deliberately not parameters here — Apple's own Workout app asks the swimmer for pool length and location when they actually start the workout, and auto-scales distances/times to match, so there's nothing for this tool to set. display_name: come up with a short, specific, memorable title based on what this workout actually is (e.g. "Threshold 100s", "IM Ladder") — not a generic label like "Swim Workout" every time. Shown as this workout's title on the Watch/Fitness app and in Lion Lift's own Sync Workouts list, where several of these can be listed side by side. scheduled_for: "YYYY-MM-DDTHH:MM", 24-hour, the user's local time — when they intend to do this swim. Confirm "today"/"tomorrow" explicitly rather than assuming a timezone, same as schedule_lift. blocks: at least one SwimIntervalBlockInput. Each has: - iterations (int, default 1): how many times the work/recovery pair repeats. - work (required) / recovery (optional): each a SwimStepInput — see below. warmup / cooldown: optional single SwimStepInputs (no iteration count). A SwimStepInput is: {goal, alert?, display_name?}. - display_name: optional label for that one step — either descriptive (e.g. "Kick Set") or the stroke type (e.g. "Freestyle", "Backstroke", "Breaststroke", "Butterfly", "IM"). - goal (a SwimGoalInput): {type, ...}. type is one of: "open" — no fields needed, manual advance. "time" — needs seconds (float). "distance" — needs meters (float). "energy" — needs kilocalories (float). "poolSwimDistanceWithTime" — needs BOTH meters and seconds — a combined distance-and-time target (e.g. "100m within 1:30"); the step only advances once both are met, not just whichever comes first. - alert (a SwimAlertInput, optional): {type, ...}. No pace/speed option — there's no GPS in a pool. type is one of: "heartRateZone" — needs zone (int, e.g. 1-5). "heartRateRange" — needs bpm_low, bpm_high. "powerZone" — needs zone (int). "powerRange" — needs watts_low, watts_high. "powerThreshold" — needs watts. "cadenceRange" — needs spm_low, spm_high (strokes/min). "cadenceThreshold" — needs spm (strokes/min). Example — "10x100m freestyle on a 1:30 interval, with a 200m warmup and 200m cooldown": warmup = {"goal": {"type": "distance", "meters": 200}} blocks = [{ "iterations": 10, "work": { "goal": {"type": "poolSwimDistanceWithTime", "meters": 100, "seconds": 90}, "display_name": "Freestyle", }, }] cooldown = {"goal": {"type": "distance", "meters": 200}}
schedule_pool_swim_workout
Lion Lift ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Lion Lift's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Lion Lift alternatives on ChatGPT?
As of 2026-10-20, Lion Lift competes with AI Endurance, Athlete Space, Boulie, Coach to Wrist, COROS, Eixo Run, Endorphins Running, Endurance Planner and 20 more in ChatGPT Endurance Sport Training Planners, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.