I Built an AI That Reads My Recovery Data Every Morning — Here's What It Actually Outputs
Why I Built This
The problem sounds simple: I have too much data from too many devices that don't talk to each other.
WHOOP 5.0, Garmin Forerunner 265S, 8Sleep Pod, Speediance Gym Monster 2S — plus calorie tracking through Chronometer. Each device lives in its own app, its own ecosystem, its own walled garden. Speediance doesn't have a web app. Tonal didn't either. WHOOP's web app has gotten progressively worse over the past two years. None of them are designed to talk to each other in any meaningful way.
So I ended up doing what I always do with data problems: I built something.
About a week into running OpenClaw on an M1 Mac Mini I had collecting dust, I had a working fitness intelligence system that pulls from six connectors and generates two reports: a **morning report** that tells me how hard I should train, and a **nightly report** that evaluates how the day went. Both post automatically to a hosted dashboard (GitHub Pages) that I can check from anywhere.
The Stack
**Hardware:** M1 Mac Mini as the base agent host. I have three OpenClaw instances running — Arya (handles the fitness dashboard and Kanban board), Bob (assistant/reminders/home automation), and Claude (backup/verification). The fitness system runs on Arya.
**Models:** Primary orchestration through a paid Miniax M2.5 plan ($10/month), which is reliable and slow enough to properly delegate tasks without burning tokens. When I need heavy lifting — multi-step integration work, debugging, building new connectors — I switch Arya temporarily to Claude (Anthropic). For routine daily report generation, the $10 plan handles it.
**Connectors (6 active):**
- WHOOP API (recovery score, HRV, sleep data, strain)
- Garmin Connect (activity data — runs, HR zones, pace, training load)
- Speediance (via the unofficial API endpoint from the Reddit community — it pulls completed workout data including volume, exercise breakdown, and 1RM estimates)
- 8Sleep (sleep score, temperature, HRV from the Pod)
- Chronometer (calorie and macro data)
- Apple Health (bridge layer that lets Speediance calorie data reach WHOOP for accurate strain calculation)
The Speediance connector is the one people ask about most. There's no official API. Someone in the Reddit community published the endpoint that returns your completed workout data. OpenClaw found it, I pointed it at the URL, and within minutes it was pulling down my workout history and piping it into the dashboard. The whole workflow — download the unofficial Speediance manager, decompile it, identify the data endpoint, build a connector — took the agent less time than it would have taken me to do it manually.
What the Morning Report Actually Looks Like
Here's the real output from **February 11, 2026** — the 18% WHOOP recovery day:
---
**MORNING FITNESS REPORT — February 11, 2026**
*Data sources: WHOOP, Garmin, 8Sleep, Speediance, Chronometer*
**Recovery Summary:**
- WHOOP Recovery: 18% 🔴
- HRV: 18.7ms (below 7-day baseline)
- Total Sleep (WHOOP): 3.5h
- 8Sleep Score: 61/100
- Previous day WHOOP Strain: 11.6
**Training Load (Last 7 days):**
- Speediance volume: 94,280 lbs
- Runs logged: 4 sessions, 8.9 miles
- Highest intensity session: Feb 8 anaerobic run
**⚠️ Flags:**
- Sleep debt detected (>2h below baseline)
- Caloric intake yesterday: 792 kcal (estimated deficit of ~800 kcal vs. maintenance)
- Injury risk elevated: acute sleep deprivation + caloric deficit
**Recommendation: Active Recovery**
*Confidence: 77.8% | Weighted Score: 55.65*
Reasoning: HRV is depressed relative to rolling baseline. Sleep debt is the primary driver — 3.5h is clinically insufficient for neuromotor recovery. Caloric deficit compounds recovery suppression. Previous strain of 11.6 was moderate and would normally support a light session, but the combination of all three negative inputs (sleep, calories, HRV) shifts the recommendation to Active Recovery only. A light Zone 1 run of 20–30 minutes is acceptable. Speediance Warrior 1 at working weight: not recommended today. BJJ: not recommended (degraded reaction time risk).
---
That's the actual output. Not a generic "rest today" — a reasoned recommendation with the specific inputs surfaced, the confidence level shown, and the BJJ call made explicitly because the system knows I do jiu-jitsu and that BJJ has a different injury risk profile than a lifting session.
The 77.8% confidence number matters. When confidence is lower — say, 55% — I dig into which signals are conflicting. In this case, the previous day's strain wasn't high enough to independently demand rest, but the three other negative signals outvoted it. The model shows its work.
The Nightly Report
The nightly report runs after I've had time to log the day's activities. It evaluates:
- Did training match the morning recommendation?
- What was the actual WHOOP strain accumulated?
- Speediance volume if a lifting session happened
- Calorie close-out from Chronometer
- Any new 1RM PRs from Speediance
- Run data from Garmin if applicable
It posts to the same dashboard. Over time, I can look back and see whether I followed the morning recommendations and what the outcome was — did I override a red day and feel worse two days later? Did I train on a yellow day and post a PR? The dataset builds into something useful.
What Building It Actually Taught Me
I expected this to take weeks. It took about a week of evenings. Most of that was the initial setup on the Mac Mini and building the first working connector. Once OpenClaw had one connector working, building the next one was faster. Once it had the data, building the visualization layer was faster still.
The frustrating parts: the free models (Google AI Studio, Nvidia Kimmy K2.5) make major mistakes under complex multi-step workloads. Google's model once deleted its own core configuration files by running a git clean at the wrong scope. Nvidia's is faster when it works and completely silent when it doesn't. For building and debugging, nothing matches Claude with a proper API key — but that burns tokens fast. The solution I landed on is: Miniax for daily scheduled runs, Claude on demand when I'm actively building something new.
The Speediance data pipeline required the most patience. The unofficial endpoint isn't documented. The agent had to inspect the network requests from the unofficial Speediance manager app, identify the right endpoint, figure out the auth pattern, and build a connector that handles pagination properly. It did all of that. I watched it work through it in the logs. That moment — seeing it successfully pull 125 completed workouts with full exercise breakdowns — was when I understood why people describe this technology as genuinely different from anything that came before.
The Bigger Picture
I've been doing fitness tech for years. I had a Microsoft Band before Apple Watch existed. I've used every generation of WHOOP. I've owned Tonal. I've owned two Speediances. I've tracked calories through every app that ever existed in the space.
What this system does that nothing else has done is put all of that data **in the same room** and let something with actual reasoning capability look at it together. Not a dashboard of disconnected widgets. An agent that can look at my HRV trend, my lifting volume from last week, my caloric intake, and my sleep data simultaneously and make a judgment call that accounts for all of it.
Is it perfect? No. The calorie data pipeline is still messy — I'm building an Apple Health bridge for Snap Cow data from my recent trip. The Speediance connector occasionally misses a workout if the unofficial API times out. The BJJ strain problem is real: WHOOP can detect that a jiu-jitsu session elevated my heart rate, but it can't assess the neuromotor and grip-fatigue component the way a knowledgeable coach could.
But on February 11, when it told me 18% recovery, 77.8% confidence, Active Recovery — it was right. And it told me before I'd even gotten out of bed.
That's the version of fitness technology I've been trying to build since I first started tracking this stuff. It just took the right platform to make it possible.