Fitness Dashboard — Agent Documentation
Complete guide for AI agents operating Sandy's fitness tracking system. This documentation covers the training philosophy, available data, API operations, and recommended workflows.
Quick Start for Agents
- Read the Training Philosophy — understand the four-vector model
- Review Context Sources — know what data is available
- Study Common Workflows — learn how to design workouts
- Reference API Documentation — for implementation details
Training Philosophy
Sandy trains with a four-vector model. Every workout must contribute to at least one vector. These vectors are fixed — do not invent new ones.
| Vector | What It Measures | Unit |
|---|---|---|
| Strength | Peak load per movement plane | kg |
| Endurance | Total session volume (sets × reps × weight) | kg |
| Efficiency | Volume per minute of working time | kg/min |
| Mobility | Quality of movement, range, symmetry | Qualitative (Good/Fair/Poor) |
Movement Planes
Every exercise maps to exactly one movement plane:
Push— Horizontal pushing (push-ups, bench press)Pull— Horizontal pulling (rows, pull-ups)Press— Vertical pushing (overhead press, lateral raises)Hinge— Hip hinge (swings, deadlifts, cleans, get-ups)Squat— Bilateral squat pattern (goblet squats)SideSquat— Unilateral/lateral squat (cossacks, side lunges)Twist— Rotational/anti-rotational (windmills, Turkish get-ups)Run— Locomotion (sprints, running)
Authentication
Every API call requires authentication. Prefer JWT tokens via the Authorization: Bearer <token> header. Legacy API key fallback uses X-API-Key.
Base URLs
- Production:
https://fitness-dashboard.netlify.app/api - Local Dev:
http://localhost:8888/api
How Agents Should Operate
Core Principles
- Read before writing — Always check existing data (goals, recent workouts, equipment) before making recommendations
- Respect the four vectors — Every workout design must address at least one vector
- Use correct movement planes — Never invent new planes; use the 8 defined ones
- Work within equipment constraints — Only recommend exercises with available equipment
- Track progress toward goals — Reference active goals when giving advice
Designing a Workout
When designing a new workout, agents should:
- Query
/goals— identify active targets - Query
/equipment— know what's available - Query recent
/workouts— see what was done recently - Query
/analytics/summary— understand current capacity - Design balanced workout covering needed vectors
- POST to
/workoutswith statusplanned
Logging a Completed Workout
- Take raw input from user (what they did)
- Parse into structured exercises with movement planes
- Calculate volume (sets × reps × weight)
- POST to
/workoutswith statuslogged - POST exercises linked to workout
- Update workout with
analysedstatus when complete
Context Sources
Agents have access to the following data sources to inform decisions:
| Source | Endpoint | Purpose |
|---|---|---|
| Active Goals | GET /goals | What vectors/planes to prioritize |
| Equipment Inventory | GET /equipment | What weights/tools are available |
| Workout History | GET /workouts | Recent training patterns |
| Analytics Summary | GET /analytics/summary | Aggregate stats by vector/plane |
| Agent Outputs | GET /agent-outputs | Previous advice and analyses |
| Meta Analysis | GET /analysis-cycles | Periodic aggregated insights |
Common Workflows
1. Design Next Workout
// Step 1: Get context
GET /goals?status=Active
GET /equipment
GET /workouts?limit=5&status=analysed
GET /analytics/summary
// Step 2: Analyze gaps
- Which goals are behind?
- Which planes haven't been trained recently?
- What equipment is available?
// Step 3: Design workout
POST /workouts
{
"date": "2026-04-23",
"type": "KB",
"status": "planned",
"title": "KB Push/Pull Focus",
"intensity": "Moderate",
"exercises": [...]
}
2. Log Completed Workout
// Step 1: Create workout entry
POST /workouts
{
"date": "2026-04-23",
"type": "KB",
"status": "logged",
"duration_minutes": 35,
"intensity": "Hard",
"notes": "User raw input: '8:15 start. 5x10 double cleans @ 12kg...'"
}
// Step 2: Add exercises
POST /exercises (for each exercise)
{
"workout_id": "w_xxx",
"name": "Double KB Cleans",
"movement_plane": "Hinge",
"actual_sets": 5,
"actual_reps": 10,
"actual_weight_kg": 24,
"volume_kg": 1200,
"status": "completed"
}
// Step 3: Upload photo to Netlify Blobs
POST /api/blobs/upload
{ "data": "base64encodedstring...", "content_type": "image/jpeg" }
// Step 4: Attach blob key to workout
PUT /workouts/w_xxx
{ "photo_key": "blob_xxx..." }
// Step 5: Mark complete
PUT /workouts/w_xxx
{ "status": "analysed" }
3. Generate Periodic Analysis
// Step 1: Get recent completed workouts
GET /workouts?status=analysed&date_from=2026-04-01
// Step 2: Analyze patterns
- Volume trends
- Plane coverage
- Goal progress
- Strength/efficiency changes
// Step 3: Store meta-analysis
POST /analysis-cycles
{
"start_date": "2026-04-01",
"end_date": "2026-04-21",
"workouts_analyzed": 12,
"summary": "Weekly analysis...",
"recommendations": "Next week focus on..."
}
API Overview
The REST API follows standard patterns with JSON request/response bodies. All endpoints require authentication.
Response Format
{
"data": [...], // Array of results
"total": 42, // Total count (for pagination)
"limit": 20, // Page size
"offset": 0 // Current offset
}
Error Format
{
"error": "NotFound",
"message": "Workout not found"
}
Workouts API
| Method | Endpoint | Description |
|---|---|---|
| GET | /workouts | List workouts with optional filters |
| POST | /workouts | Create new workout |
| GET | /workouts/:id | Get single workout with exercises |
| PUT | /workouts/:id | Update workout |
| DELETE | /workouts/:id | Delete workout |
Query Parameters
type— Filter by workout type (KB, GYM, PB, Yoga, Other)status— Filter by status (planned, logged, analysed). Comma-separated for multiple.date_from— Start date (YYYY-MM-DD)date_to— End date (YYYY-MM-DD)limit— Page size (default 20)offset— Pagination offset
Workout Statuses
- planned — Future workout, not yet performed
- logged — Completed but awaiting analysis
- analysed — Fully processed and counted
Exercises API
Exercises are always linked to a workout. They represent individual movements with volume tracking.
| Method | Endpoint | Description |
|---|---|---|
| GET | /workouts/:id/exercises | List exercises for a workout |
| POST | /exercises | Add exercise to workout |
| PUT | /exercises/:id | Update exercise |
| DELETE | /exercises/:id | Delete exercise |
Exercise Fields
name— Exercise name (e.g., "Double KB Cleans")movement_plane— One of: Push, Pull, Press, Hinge, Squat, SideSquat, Twist, Runplanned_sets/reps/weight— Targets for the exerciseactual_sets/reps/weight— What was actually donevolume_kg— Calculated: sets × reps × weightstatus— completed, modified, skipped
Equipment API
Inventory of available fitness equipment. Used by agents to design feasible workouts.
| Method | Endpoint | Description |
|---|---|---|
| GET | /equipment | List all equipment |
| POST | /equipment | Add new equipment |
| PUT | /equipment/:id | Update equipment |
| DELETE | /equipment/:id | Delete equipment |
Categories
KB— KettlebellsDB— DumbbellsBarbell— Barbells and platesMachine— Weight machinesOther— Miscellaneous equipment
Goals API
Goal tracking organized by training vector and optional movement plane.
| Method | Endpoint | Description |
|---|---|---|
| GET | /goals | List all goals |
| POST | /goals | Create new goal |
| GET | /goals/:id | Get single goal |
| PUT | /goals/:id | Update goal progress |
| DELETE | /goals/:id | Delete goal |
Goal Vectors
Strength— Peak load targetsEndurance— Total volume targetsEfficiency— kg/min targetsMobility— Range/quality targets
Goal Statuses
- Active — Currently pursuing
- Achieved — Target reached
- Paused — Temporarily suspended
- Abandoned — No longer pursuing
Analytics API
Aggregate statistics for tracking progress across vectors and movement planes.
GET /analytics/summary
Returns aggregate metrics. Optionally filter by date range with date_from and date_to query params.
{
"total_workouts": 42,
"total_volume_kg": 45000,
"avg_efficiency": 145.5,
"by_type": { "KB": 35, "GYM": 7 },
"by_vector": {
"Strength": { "peak_load_kg": 60, "exercises": 120 },
"Endurance": { "total_volume_kg": 45000 },
"Efficiency": { "avg_kg_per_min": 145.5 },
"Mobility": { "sessions_count": 42 }
},
"by_movement_plane": {
"Hinge": { "total_volume": 15000, "peak_load": 60 },
"Press": { "total_volume": 8000, "peak_load": 32 }
}
}
Data Model Reference
Workouts Table
| Field | Type | Description |
|---|---|---|
| id | TEXT | Unique identifier |
| title | TEXT | Human-readable workout name |
| date | DATE | Workout date (YYYY-MM-DD) |
| type | TEXT | KB, GYM, PB, Yoga, Other |
| status | TEXT | planned, logged, analysed |
| intensity | TEXT | Light, Moderate, Hard |
| duration_minutes | INTEGER | Total session time |
| working_time_minutes | INTEGER | Active work time only |
| total_volume_kg | REAL | Sum of all exercise volumes |
| efficiency_kg_per_min | REAL | Volume / working_time |
| notes | TEXT | User or agent notes |
| photo_url | TEXT | Workout photo blob key |
Exercises Table
| Field | Type | Description |
|---|---|---|
| id | TEXT | Unique identifier |
| workout_id | TEXT | Parent workout reference |
| name | TEXT | Exercise name |
| movement_plane | TEXT | Push, Pull, Press, Hinge, Squat, SideSquat, Twist, Run |
| planned_sets/reps/weight | INTEGER/REAL | Target values |
| actual_sets/reps/weight | INTEGER/REAL | Actual values |
| volume_kg | REAL | Calculated: sets × reps × weight |
| status | TEXT | completed, modified, skipped |
| order_index | INTEGER | Sequence in workout |
Statuses & Enums
Photo Upload
Photos are uploaded via Netlify Blobs. The frontend uploads the file to POST /api/blobs/upload, which returns a blob key. The photo_url field on the workout stores this key.
To display a photo, use GET /api/blobs/<key>. Agents should use the blob endpoints rather than storing base64 data in the database.
Workout Status Lifecycle
planned → logged → analysed
- planned — Workout designed but not yet performed. Shows in "Next Workout" box.
- logged — Workout completed but data not fully processed. Not counted in analytics.
- analysed — Fully processed workout. Counted in all statistics and analytics.
Exercise Status
completed— Done as plannedmodified— Changed during workout (different reps/weight)skipped— Not performed
Workout Types
KB— Kettlebell trainingGYM— Gym/machine workPB— Plyo/box workYoga— Yoga sessionOther— Miscellaneous