Intervals icu
Evidence-based training skills for AI agents
npx -y skills add disco-trooper/skills --skill intervals-icuAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Intervals.icu API workflows for fetching and updating wellness, activities, fitness metrics, events, zones, power curves, activity streams, and uploads. Use when Codex needs to call Intervals.icu, prepare authenticated API commands, export athlete data, debug API responses, or pair platform data with cycling-training analysis.
SKILL.md
11.9 KB, as published. Nobody here has run it
Intervals.icu API Skill
Skill Relationship
┌─────────────────┐ fetch data ┌───────────────────┐
│ intervals-icu │ ──────────────────► │ cycling-training │
│ (DATA API) │ │ (ANALYSIS) │
│ │ ◄────────────────── │ │
│ • wellness │ interpret results │ • zone calc │
│ • activities │ │ • periodization │
│ • power curves │ │ • workout design │
│ • fitness │ │ • load management │
└─────────────────┘ └───────────────────┘
Usage pattern:
- Use
intervals-icuto fetch data from API - Use
cycling-trainingto analyze and interpret - Use
intervals-icuto update wellness/events
API wrapper for intervals.icu cycling training platform. Designed to work alongside the cycling-training skill.
Quick Start
# Set credentials (one-time)
export INTERVALS_API_KEY="your_api_key"
export INTERVALS_ATHLETE_ID="iXXXXX"
# Set skill directory for local installs
SKILLS_DIR="<path-to-your-skills-dir>"
# Use the API helper
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness today
"$SKILLS_DIR/intervals-icu/scripts/api.sh" activities 2024-01-01 2024-01-31
Authentication
Get your API key from https://intervals.icu/settings → Developer Settings → API Key.
Find athlete ID in the URL when logged in: intervals.icu/athlete/iXXXXX/...
Rate Limiting
Intervals.icu API has rate limits. The script handles this with:
- Automatic retry with exponential backoff (default: 3 attempts)
- Configurable via
INTERVALS_MAX_RETRIESenvironment variable
# Increase retries for bulk operations
export INTERVALS_MAX_RETRIES=5
If you hit rate limits frequently:
- Add delays between bulk requests:
sleep 1 - Use date ranges instead of individual requests
- Cache responses locally for analysis
Prerequisites
- curl - Pre-installed on most systems
- jq -
brew install jq(macOS) /apt install jq(Linux) - bats-core - Optional, for tests:
brew install bats-core
API Helper Script
Use scripts/api.sh to handle authentication and common operations:
| Command | Description |
|---|---|
api.sh wellness [date] | Get wellness for date (default: today) |
api.sh wellness-range <start> <end> | Get wellness for date range |
api.sh wellness-update <date> <json> | Update wellness fields |
api.sh activities <start> <end> [format] [--all] | List activities (--all for pagination) |
api.sh activity <id> | Get single activity details |
api.sh activity-streams <id> [types] | Get activity data streams |
api.sh activity-upload <file> | Upload activity (.fit, .gpx, .tcx) |
api.sh athlete | Get athlete profile |
api.sh fitness | Get current CTL/ATL/TSB |
api.sh zones | Get power/HR zone settings |
api.sh events <start> <end> | Get planned events/workouts |
api.sh event-create <date> <json> | Create planned workout/event |
api.sh power-curves <start> <end> [format] | Power curves (json/summary/seconds) |
Examples
# Get today's wellness
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness
# Get wellness for specific date
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness 2024-01-15
# Update wellness (weight and sleep)
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-update 2024-01-15 '{"weight": 72.5, "sleepSecs": 28800}'
# Get last month's activities
"$SKILLS_DIR/intervals-icu/scripts/api.sh" activities 2024-01-01 2024-01-31
# Export activities as CSV
"$SKILLS_DIR/intervals-icu/scripts/api.sh" activities 2024-01-01 2024-01-31 csv > activities.csv
Direct curl Examples
For custom operations not covered by the helper:
# Base URL
BASE="https://intervals.icu/api/v1"
# Auth header
AUTH="Authorization: Basic $(echo -n "API_KEY:$INTERVALS_API_KEY" | base64)"
# Get power curve
curl -s -H "$AUTH" "$BASE/athlete/$INTERVALS_ATHLETE_ID/power-curves?oldest=2024-01-01&newest=2024-12-31"
# Get streams for activity
curl -s -H "$AUTH" "$BASE/activity/iXXXX/streams?types=watts,heartrate,cadence"
# Upload activity
curl -s -H "$AUTH" -F "[email protected]" "$BASE/athlete/$INTERVALS_ATHLETE_ID/activities"
Key Endpoints Reference
| Endpoint | Method | Purpose |
|---|---|---|
/athlete/{id} | GET | Athlete profile |
/athlete/{id}/wellness/{date} | GET/PUT | Wellness data |
/athlete/{id}/wellness | GET | Wellness range (add ?oldest=&newest=) |
/athlete/{id}/activities | GET | Activities list |
/activity/{id} | GET | Activity details |
/activity/{id}/streams | GET | Activity data streams |
/athlete/{id}/events | GET | Planned workouts/events |
/athlete/{id}/power-curves | GET | Power duration curves |
Wellness Fields
| Field | Type | Range | Description |
|---|---|---|---|
weight | float | 30-200 kg | Body weight |
restingHR | int | 30-100 bpm | Resting heart rate |
hrv | float | 10-150 ms | HRV RMSSD (typical: 20-80) |
hrvSDNN | float | 10-200 ms | HRV SDNN |
sleepSecs | int | 0-43200 | Sleep duration (0-12h in seconds) |
sleepScore | float | 0-100 | Sleep quality percentage |
sleepQuality | int | 1-5 | 1=poor, 5=excellent |
fatigue | int | 1-5 | 1=fresh, 5=exhausted |
mood | int | 1-5 | 1=bad, 5=great |
motivation | int | 1-5 | Training motivation |
readiness | int | 1-5 | Training readiness |
stress | int | 1-5 | Stress level |
soreness | int | 1-5 | Muscle soreness |
ctl | float | 0-200 | Chronic Training Load (fitness) |
atl | float | 0-300 | Acute Training Load (fatigue) |
rampRate | float | -10 to +10 | CTL weekly change rate |
Integrate with cycling-training
Use both skills together:
-
Fetch data with intervals-icu skill:
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-range 2024-01-01 2024-01-31 > wellness.json "$SKILLS_DIR/intervals-icu/scripts/api.sh" activities 2024-01-01 2024-01-31 > activities.json -
Analyze with cycling-training skill:
- Calculate training load distribution
- Check polarization index
- Evaluate recovery status based on HRV trends
- Plan next mesocycle based on CTL/ATL/TSB
-
Update wellness after morning check-in:
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-update today '{"weight": 72.5, "sleepSecs": 28800, "readiness": 4}'
End-to-End Workflow Example
Complete example: Morning HRV-based workout adjustment using both skills.
Scenario
You wake up, check HRV, and want to adjust today's planned workout based on recovery status.
Step 1: Fetch morning wellness data
# Get today's wellness (HRV from device sync)
WELLNESS=$("$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness today)
echo "$WELLNESS" | jq '{hrv, restingHR, sleepSecs, ctl, atl}'
Output:
{
"hrv": 42.5,
"restingHR": 54,
"sleepSecs": 25200,
"ctl": 65.3,
"atl": 72.1
}
Step 2: Analyze with cycling-training skill
Based on the data:
- HRV: 42.5 ms (below your baseline of 50 ms = -15%)
- TSB: 65.3 - 72.1 = -6.8 (slightly fatigued)
- Sleep: 7 hours (adequate but not optimal)
cycling-training recommendation: Reduce intensity. Convert threshold workout to endurance/recovery.
Step 3: Update today's planned event
# Find today's planned workout
TODAY=$(date +%Y-%m-%d)
EVENTS=$("$SKILLS_DIR/intervals-icu/scripts/api.sh" events $TODAY $TODAY)
EVENT_ID=$(echo "$EVENTS" | jq -r '.[0].id')
# Update to easier workout
"$SKILLS_DIR/intervals-icu/scripts/api.sh" event-update "$EVENT_ID" '{
"name": "Recovery Ride (HRV adjusted)",
"description": "Original: Threshold intervals. Adjusted due to low HRV (-15% from baseline).",
"icu_training_load": 40
}'
Step 4: Log subjective wellness
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-update today '{
"readiness": 3,
"fatigue": 3,
"mood": 4,
"soreness": 2
}'
Decision Matrix
| HRV vs Baseline | TSB | Recommendation |
|---|---|---|
| >+10% | >0 | Execute as planned or add intensity |
| ±10% | >0 | Execute as planned |
| ±10% | <0 | Execute but monitor |
| <-10% | Any | Reduce intensity or rest |
| <-20% | Any | Rest day |
Testing
Run the test suite:
# Requires: bats-core
# Install: brew install bats-core (macOS) or apt install bats (Linux)
"$SKILLS_DIR/intervals-icu/tests/run_tests.sh"
Tests verify:
- Help and argument validation
- Environment variable checks
- Date parsing (cross-platform)
- JSON parsing with mock fixtures
- Power curve calculations
Troubleshooting
Common Errors
| Error | Cause | Solution |
|---|---|---|
| HTTP 401 | Invalid API key | Regenerate key in settings |
| HTTP 403 | No permission | Check athlete ID ownership |
| HTTP 404 | Resource not found | Verify date format (YYYY-MM-DD) |
| HTTP 429 | Rate limited | Wait 60s, reduce request frequency |
| "jq: command not found" | jq not installed | brew install jq (macOS) / apt install jq (Linux) |
| Empty response | No data for date range | Check date range contains activities |
| "Invalid JSON" | Malformed JSON payload | Validate JSON: `echo '{"key": "value"}' |
Debug Mode
Enable verbose output for debugging:
# Show curl commands
export INTERVALS_DEBUG=1
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness today
Common Issues
Issue: Activities not syncing from Garmin/Wahoo
- Check device sync in intervals.icu settings
- Verify connection status with fitness platform
- Manual upload:
api.sh activity-upload ride.fit
Issue: HRV not appearing in wellness
- HRV requires compatible device (Garmin, Wahoo, Oura, etc.)
- Check device sync completed before fetching
- Some devices sync HRV with delay (up to 2 hours)
Issue: Power curves show 0 for some durations
- Need activity with sustained effort at that duration
- Indoor trainers may have gaps in data
- Check activity streams:
api.sh activity-streams <id> watts
Issue: CSV export has wrong encoding
- Intervals.icu returns UTF-8
- If Excel shows garbled text: Import as UTF-8, not auto-detect
Undocumented Endpoints
For endpoints not covered by api.sh, inspect the current Intervals.icu API documentation before adding a helper command. Prefer extending scripts/api.sh with a tested command over embedding one-off curl snippets in the skill body.
Common Workflows
Morning Wellness Check-in
# Get HRV device data (if synced)
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness today
# Update subjective metrics
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-update today '{"readiness": 4, "mood": 4, "soreness": 2}'
Weekly Training Review
# Get last 7 days
END=$(date +%Y-%m-%d)
START=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d "7 days ago" +%Y-%m-%d)
"$SKILLS_DIR/intervals-icu/scripts/api.sh" activities $START $END
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-range $START $END
"$SKILLS_DIR/intervals-icu/scripts/api.sh" fitness # Current CTL/ATL/TSB
Export for Analysis
# CSV export for spreadsheet analysis
"$SKILLS_DIR/intervals-icu/scripts/api.sh" activities 2024-01-01 2024-12-31 csv > yearly_activities.csv
"$SKILLS_DIR/intervals-icu/scripts/api.sh" wellness-range 2024-01-01 2024-12-31 csv > yearly_wellness.csv