{
  "openapi": "3.1.0",
  "info": {
    "title": "Flow State Endurance API",
    "version": "1.0.0",
    "description": "Public API for AI agents and integrations to access and manage training data on Flow State Endurance.",
    "contact": {
      "name": "Flow State Endurance",
      "url": "https://reachflowstate.ai"
    }
  },
  "servers": [
    {
      "url": "https://reachflowstate.ai/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    { "apiKey": [] }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key generated from your Flow State settings. Pass as `Authorization: Bearer fse_live_...`"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "enum": ["unauthorized", "forbidden", "not_found", "rate_limited", "validation_error", "server_error"] },
              "message": { "type": "string" },
              "retry_after": { "type": "integer", "description": "Seconds until retry (only on 429)" }
            },
            "required": ["code", "message"]
          }
        }
      },
      "Workout": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "user_id": { "type": "string", "format": "uuid" },
          "date": { "type": "string", "format": "date" },
          "title": { "type": "string" },
          "sport": { "type": "string", "example": "Run" },
          "detail": { "type": "string", "nullable": true },
          "meta": { "type": "string", "nullable": true },
          "color": { "type": "string", "nullable": true },
          "structured_data": { "type": "object", "nullable": true },
          "training_plan_id": { "type": "string", "format": "uuid", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "WorkoutCreate": {
        "type": "object",
        "required": ["date", "title"],
        "properties": {
          "date": { "type": "string", "format": "date", "example": "2026-03-01" },
          "title": { "type": "string", "example": "Easy 5K" },
          "sport": { "type": "string", "default": "Run" },
          "description": { "type": "string" },
          "duration_minutes": { "type": "number" },
          "color": { "type": "string" },
          "steps": { "type": "array", "items": { "type": "object" }, "description": "Structured workout steps" },
          "training_plan_id": { "type": "string", "format": "uuid" }
        }
      },
      "WorkoutUpdate": {
        "type": "object",
        "properties": {
          "date": { "type": "string", "format": "date" },
          "title": { "type": "string" },
          "sport": { "type": "string" },
          "description": { "type": "string" },
          "color": { "type": "string" },
          "meta": { "type": "string" },
          "duration_minutes": { "type": "number" },
          "steps": { "type": "array", "items": { "type": "object" } }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "user_id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "date": { "type": "string", "format": "date" },
          "event_type": { "type": "string" },
          "race_type": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "distance_value": { "type": "number", "nullable": true },
          "distance_unit": { "type": "string", "nullable": true },
          "duration_minutes": { "type": "number", "nullable": true },
          "location": { "type": "string", "nullable": true },
          "priority": { "type": "string", "enum": ["A", "B", "C"] },
          "target_time_seconds": { "type": "number", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "EventCreate": {
        "type": "object",
        "required": ["name", "date"],
        "properties": {
          "name": { "type": "string", "example": "Boston Marathon" },
          "date": { "type": "string", "format": "date", "example": "2026-04-20" },
          "event_type": { "type": "string", "default": "race" },
          "race_type": { "type": "string", "example": "marathon" },
          "description": { "type": "string" },
          "distance_value": { "type": "number", "example": 42.195 },
          "distance_unit": { "type": "string", "example": "km" },
          "duration_minutes": { "type": "number" },
          "location": { "type": "string" },
          "priority": { "type": "string", "enum": ["A", "B", "C"], "default": "B" },
          "target_time_seconds": { "type": "number" }
        }
      },
      "EventUpdate": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "date": { "type": "string", "format": "date" },
          "event_type": { "type": "string" },
          "race_type": { "type": "string" },
          "description": { "type": "string" },
          "distance_value": { "type": "number" },
          "distance_unit": { "type": "string" },
          "duration_minutes": { "type": "number" },
          "location": { "type": "string" },
          "priority": { "type": "string", "enum": ["A", "B", "C"] },
          "target_time_seconds": { "type": "number" }
        }
      },
      "AthleteProfile": {
        "type": "object",
        "properties": {
          "user_id": { "type": "string", "format": "uuid" },
          "experience_level": { "type": "string" },
          "goal": { "type": "string" },
          "goal_race_date": { "type": "string", "format": "date", "nullable": true },
          "goal_race_name": { "type": "string", "nullable": true },
          "injury_notes": { "type": "string", "nullable": true },
          "preferred_long_run_day": { "type": "string", "nullable": true },
          "preferred_rest_days": { "type": "array", "items": { "type": "string" }, "nullable": true },
          "preferred_units": { "type": "string" },
          "max_heart_rate": { "type": "integer", "nullable": true },
          "easy_pace_seconds": { "type": "integer", "nullable": true },
          "tempo_pace_seconds": { "type": "integer", "nullable": true },
          "threshold_pace_seconds": { "type": "integer", "nullable": true },
          "vo2max_pace_seconds": { "type": "integer", "nullable": true },
          "run_pace_zones": { "type": "object", "nullable": true },
          "weekly_mileage_target": { "type": "number", "nullable": true }
        }
      },
      "AthleteProfileUpdate": {
        "type": "object",
        "properties": {
          "experience_level": { "type": "string" },
          "goal": { "type": "string" },
          "goal_race_date": { "type": "string", "format": "date" },
          "goal_race_name": { "type": "string" },
          "injury_notes": { "type": "string" },
          "preferred_long_run_day": { "type": "string" },
          "preferred_rest_days": { "type": "array", "items": { "type": "string" } },
          "preferred_units": { "type": "string" },
          "max_heart_rate": { "type": "integer" },
          "easy_pace_seconds": { "type": "integer" },
          "tempo_pace_seconds": { "type": "integer" },
          "threshold_pace_seconds": { "type": "integer" },
          "vo2max_pace_seconds": { "type": "integer" },
          "run_pace_zones": { "type": "object" },
          "weekly_mileage_target": { "type": "number" }
        }
      },
      "RecoveryStatus": {
        "type": "object",
        "properties": {
          "body_battery": { "type": "object", "nullable": true },
          "hrv": { "type": "object", "nullable": true },
          "sleep": { "type": "object", "nullable": true },
          "stress": { "type": "object", "nullable": true }
        }
      },
      "TrainingPlan": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "user_id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "status": { "type": "string" },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date", "nullable": true },
          "goal_race_date": { "type": "string", "format": "date", "nullable": true },
          "phase": { "type": "string" },
          "current_week": { "type": "integer" },
          "total_weeks": { "type": "integer", "nullable": true },
          "workout_count": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "TrainingPlanCreate": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string", "example": "Marathon Build 2026" },
          "description": { "type": "string" },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" },
          "race_date": { "type": "string", "format": "date" },
          "phase": { "type": "string", "default": "base", "enum": ["base", "build", "peak", "taper", "recovery"] },
          "goal": { "type": "string" },
          "targetTime": { "type": "string" },
          "currentLongRun": { "type": "string" }
        }
      },
      "PlanAdapt": {
        "type": "object",
        "properties": {
          "scope": { "type": "string", "enum": ["recovery"], "description": "Adaptation scope" },
          "phase": { "type": "string", "enum": ["base", "build", "peak", "taper", "recovery"] },
          "weeksAhead": { "type": "integer" },
          "end_date": { "type": "string", "format": "date" },
          "reason": { "type": "string" }
        }
      },
      "GarminSyncRequest": {
        "type": "object",
        "properties": {
          "plan_id": { "type": "string", "format": "uuid" },
          "workout_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" }
        }
      }
    },
    "parameters": {
      "pathId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "uuid" }
      }
    }
  },
  "paths": {
    "/workouts": {
      "get": {
        "operationId": "listWorkouts",
        "summary": "List workouts",
        "description": "Retrieve workouts within a date range. Defaults to today + 2 weeks.",
        "tags": ["Workouts"],
        "parameters": [
          { "name": "from", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Start date (default: today)" },
          { "name": "to", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "End date (default: today + 14 days)" },
          { "name": "sport", "in": "query", "schema": { "type": "string" }, "description": "Filter by sport (case-insensitive partial match)" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 200 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": {
          "200": {
            "description": "List of workouts",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Workout" } }, "meta": { "type": "object", "properties": { "total": { "type": "integer" }, "from": { "type": "string" }, "to": { "type": "string" }, "limit": { "type": "integer" }, "offset": { "type": "integer" } } } } } } }
          },
          "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Rate limited", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      },
      "post": {
        "operationId": "createWorkout",
        "summary": "Create a workout",
        "tags": ["Workouts"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WorkoutCreate" } } } },
        "responses": {
          "201": { "description": "Created workout", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Workout" } } } } } },
          "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "401": { "description": "Unauthorized" },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/workouts/{id}": {
      "get": {
        "operationId": "getWorkout",
        "summary": "Get a workout",
        "tags": ["Workouts"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "responses": {
          "200": { "description": "Workout details", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Workout" } } } } } },
          "404": { "description": "Not found" }
        }
      },
      "put": {
        "operationId": "updateWorkout",
        "summary": "Update a workout",
        "tags": ["Workouts"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WorkoutUpdate" } } } },
        "responses": {
          "200": { "description": "Updated workout", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Workout" } } } } } },
          "404": { "description": "Not found" }
        }
      },
      "delete": {
        "operationId": "deleteWorkout",
        "summary": "Delete a workout",
        "tags": ["Workouts"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "responses": {
          "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "deleted": { "type": "boolean" }, "id": { "type": "string" } } } } } } } },
          "404": { "description": "Not found" }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "listEvents",
        "summary": "List events",
        "tags": ["Events"],
        "parameters": [
          { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "priority", "in": "query", "schema": { "type": "string", "enum": ["A", "B", "C"] } }
        ],
        "responses": {
          "200": { "description": "List of events", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Event" } }, "meta": { "type": "object", "properties": { "total": { "type": "integer" } } } } } } } }
        }
      },
      "post": {
        "operationId": "createEvent",
        "summary": "Create an event",
        "tags": ["Events"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EventCreate" } } } },
        "responses": {
          "201": { "description": "Created event", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Event" } } } } } }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "operationId": "getEvent",
        "summary": "Get an event",
        "tags": ["Events"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "responses": {
          "200": { "description": "Event details", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Event" } } } } } },
          "404": { "description": "Not found" }
        }
      },
      "put": {
        "operationId": "updateEvent",
        "summary": "Update an event",
        "tags": ["Events"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EventUpdate" } } } },
        "responses": {
          "200": { "description": "Updated event", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Event" } } } } } },
          "404": { "description": "Not found" }
        }
      },
      "delete": {
        "operationId": "deleteEvent",
        "summary": "Delete an event",
        "tags": ["Events"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "responses": {
          "200": { "description": "Deleted" },
          "404": { "description": "Not found" }
        }
      }
    },
    "/athletes/{id}": {
      "get": {
        "operationId": "getAthlete",
        "summary": "Get athlete profile",
        "description": "Use `me` as the id to get your own profile.",
        "tags": ["Athletes"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Athlete user ID or `me`" }],
        "responses": {
          "200": { "description": "Athlete profile", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AthleteProfile" } } } } } },
          "404": { "description": "Not found" }
        }
      },
      "put": {
        "operationId": "updateAthlete",
        "summary": "Update athlete profile",
        "tags": ["Athletes"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Athlete user ID or `me`" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AthleteProfileUpdate" } } } },
        "responses": {
          "200": { "description": "Updated profile", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AthleteProfile" } } } } } }
        }
      }
    },
    "/athletes/{id}/recovery": {
      "get": {
        "operationId": "getRecovery",
        "summary": "Get recovery metrics",
        "description": "Body battery, HRV, sleep, and stress data from Garmin.",
        "tags": ["Athletes"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Athlete user ID or `me`" }],
        "responses": {
          "200": { "description": "Recovery status", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/RecoveryStatus" } } } } } }
        }
      }
    },
    "/plans": {
      "post": {
        "operationId": "createPlan",
        "summary": "Create a training plan",
        "tags": ["Plans"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TrainingPlanCreate" } } } },
        "responses": {
          "201": { "description": "Created plan", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TrainingPlan" } } } } } }
        }
      }
    },
    "/plans/{id}": {
      "get": {
        "operationId": "getPlan",
        "summary": "Get a training plan",
        "tags": ["Plans"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "responses": {
          "200": { "description": "Plan details with computed fields (current_week, total_weeks, workout_count)", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TrainingPlan" } } } } } },
          "404": { "description": "Not found" }
        }
      }
    },
    "/plans/{id}/adapt": {
      "put": {
        "operationId": "adaptPlan",
        "summary": "Adapt a training plan",
        "description": "Modify plan phase, extend dates, or trigger recovery adaptation.",
        "tags": ["Plans"],
        "parameters": [{ "$ref": "#/components/parameters/pathId" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlanAdapt" } } } },
        "responses": {
          "200": { "description": "Adapted plan", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TrainingPlan" } } } } } },
          "404": { "description": "Not found" }
        }
      }
    },
    "/sync/garmin": {
      "post": {
        "operationId": "syncGarmin",
        "summary": "Sync workouts to Garmin",
        "description": "Push workouts to Garmin Connect. Defaults to next 2 weeks if no filters specified.",
        "tags": ["Sync"],
        "requestBody": { "required": false, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GarminSyncRequest" } } } },
        "responses": {
          "200": { "description": "Sync result", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "synced": { "type": "integer" }, "workout_ids": { "type": "array", "items": { "type": "string" } }, "garmin_result": { "type": "object" } } } } } } } }
        }
      }
    }
  },
  "tags": [
    { "name": "Workouts", "description": "Manage planned and completed workouts" },
    { "name": "Events", "description": "Manage races and events" },
    { "name": "Athletes", "description": "Athlete profile and recovery data" },
    { "name": "Plans", "description": "Training plan management" },
    { "name": "Sync", "description": "Sync workouts to external platforms" }
  ]
}
