{
  "x-generator": "NSwag v14.2.0.0 (NJsonSchema v11.1.0.0 (Newtonsoft.Json v13.0.0.0))",
  "openapi": "3.0.0",
  "info": {
    "title": "Gravl API",
    "description": "REST API for reading a Gravl user's training data with their consent. Authenticate with an OAuth 2.0 authorization-code flow or a scoped personal access token. Every operation lists the scope it requires. Errors are RFC 9457 application/problem+json. Documentation: https://gravl.ai/developers",
    "termsOfService": "https://gravl.ai/terms",
    "contact": {
      "name": "Gravl developer support",
      "url": "https://gravl.ai/developers",
      "email": "developers@gravl.ai"
    },
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://api.gravl.ai"
    }
  ],
  "paths": {
    "/oauth/token": {
      "post": {
        "tags": [
          "OAuthToken"
        ],
        "summary": "Exchange an authorization code for tokens, or refresh an access token.",
        "operationId": "OAuthToken_Token",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "nullable": true
                  },
                  "client_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "client_secret": {
                    "type": "string",
                    "nullable": true
                  },
                  "code": {
                    "type": "string",
                    "nullable": true
                  },
                  "redirect_uri": {
                    "type": "string",
                    "nullable": true
                  },
                  "code_verifier": {
                    "type": "string",
                    "nullable": true
                  },
                  "refresh_token": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "tags": [
          "OAuthToken"
        ],
        "summary": "RFC 7009 revocation. Always 200 for authenticated clients, regardless of token state.",
        "operationId": "OAuthToken_Revoke",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "client_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "client_secret": {
                    "type": "string",
                    "nullable": true
                  },
                  "token": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/equipment": {
      "get": {
        "tags": [
          "PublicEquipment"
        ],
        "summary": "The global equipment catalog (paginated).",
        "operationId": "PublicEquipment_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicEquipmentDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exercises:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/equipment/{id}": {
      "get": {
        "tags": [
          "PublicEquipment"
        ],
        "summary": "One catalog equipment item.",
        "operationId": "PublicEquipment_GetById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicEquipmentDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exercises:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/exercises": {
      "get": {
        "tags": [
          "PublicExercises"
        ],
        "summary": "The global exercise catalog (paginated, searchable).",
        "operationId": "PublicExercises_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          },
          {
            "name": "Search",
            "in": "query",
            "schema": {
              "type": "string",
              "nullable": true
            },
            "x-position": 3
          },
          {
            "name": "Submuscle",
            "in": "query",
            "schema": {
              "nullable": true,
              "oneOf": [
                {
                  "$ref": "#/components/schemas/Submuscle"
                }
              ]
            },
            "x-position": 4
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicExerciseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exercises:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/exercises/{id}": {
      "get": {
        "tags": [
          "PublicExercises"
        ],
        "summary": "One catalog exercise.",
        "operationId": "PublicExercises_GetById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicExerciseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exercises:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/measurements": {
      "get": {
        "tags": [
          "PublicMeasurements"
        ],
        "summary": "The user's body measurements (paginated, date filters).",
        "operationId": "PublicMeasurements_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          },
          {
            "name": "StartDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            },
            "x-position": 3
          },
          {
            "name": "EndDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            },
            "x-position": 4
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicMeasurementDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "measurements:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/personal-records": {
      "get": {
        "tags": [
          "PublicPersonalRecords"
        ],
        "summary": "The user's personal records, filterable by exercise.",
        "operationId": "PublicPersonalRecords_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          },
          {
            "name": "ExerciseId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "nullable": true
            },
            "x-position": 3
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicPersonalRecordDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "records:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/splits": {
      "get": {
        "tags": [
          "PublicSplits"
        ],
        "summary": "The user's custom training splits (paginated).",
        "operationId": "PublicSplits_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicSplitDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "splits:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/splits/{externalId}": {
      "get": {
        "tags": [
          "PublicSplits"
        ],
        "summary": "One custom split with its sessions.",
        "operationId": "PublicSplits_GetById",
        "parameters": [
          {
            "name": "externalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "guid"
            },
            "x-position": 1
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSplitDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "splits:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/stats": {
      "get": {
        "tags": [
          "PublicStats"
        ],
        "summary": "The user's training stats: streak, workouts this week, total XP and trophy count.",
        "operationId": "PublicStats_Get",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStatsDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "stats:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/trophies": {
      "get": {
        "tags": [
          "PublicTrophies"
        ],
        "summary": "The user's earned trophies (paginated).",
        "operationId": "PublicTrophies_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicTrophyDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "stats:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/user": {
      "get": {
        "tags": [
          "PublicUser"
        ],
        "summary": "The authorizing user's profile: display name, username, units and goal.",
        "operationId": "PublicUser_Get",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicUserDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "profile:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/workouts": {
      "get": {
        "tags": [
          "PublicWorkouts"
        ],
        "summary": "The user's workout history (paginated, date filters).",
        "operationId": "PublicWorkouts_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          },
          {
            "name": "StartDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            },
            "x-position": 3
          },
          {
            "name": "EndDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            },
            "x-position": 4
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicWorkoutSummaryDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "workouts:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/workouts/{externalId}": {
      "get": {
        "tags": [
          "PublicWorkouts"
        ],
        "summary": "One workout with its exercises and sets.",
        "operationId": "PublicWorkouts_GetById",
        "parameters": [
          {
            "name": "externalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "guid"
            },
            "x-position": 1
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicWorkoutDetailDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "workouts:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/workout-templates": {
      "get": {
        "tags": [
          "PublicWorkoutTemplates"
        ],
        "summary": "The user's saved workout templates (paginated).",
        "operationId": "PublicWorkoutTemplates_Get",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 1
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseOfPublicWorkoutTemplateDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "workouts:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    },
    "/api/v1/workout-templates/{externalId}": {
      "get": {
        "tags": [
          "PublicWorkoutTemplates"
        ],
        "summary": "One workout template with its planned exercises and sets.",
        "operationId": "PublicWorkoutTemplates_GetById",
        "parameters": [
          {
            "name": "externalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "guid"
            },
            "x-position": 1
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicWorkoutTemplateDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "workouts:read"
            ]
          },
          {
            "personalToken": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "PaginatedResponseOfPublicEquipmentDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicEquipmentDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicEquipmentDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string"
          },
          "subtitle": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "$ref": "#/components/schemas/EquipmentCategory"
          }
        }
      },
      "EquipmentCategory": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "None",
          "SmallWeights",
          "BarsAndPlates",
          "BenchesAndRacks",
          "CableMachines",
          "ResistanceBands",
          "Balls",
          "PlatedMachines",
          "WeightMachines",
          "Rope",
          "CardioMachines"
        ],
        "enum": [
          "None",
          "SmallWeights",
          "BarsAndPlates",
          "BenchesAndRacks",
          "CableMachines",
          "ResistanceBands",
          "Balls",
          "PlatedMachines",
          "WeightMachines",
          "Rope",
          "CardioMachines"
        ]
      },
      "PaginatedResponseOfPublicExerciseDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicExerciseDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicExerciseDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "$ref": "#/components/schemas/ExerciseCategory"
          },
          "type": {
            "$ref": "#/components/schemas/ExerciseType"
          },
          "muscle": {
            "$ref": "#/components/schemas/Muscle"
          },
          "submuscles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "secondaryMuscles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "equipment": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ExerciseCategory": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Weights",
          "Bodyweight",
          "BodyweightWithEquipment",
          "Cardio",
          "Stretching",
          "Powerlifting",
          "Warmup"
        ],
        "enum": [
          "Weights",
          "Bodyweight",
          "BodyweightWithEquipment",
          "Cardio",
          "Stretching",
          "Powerlifting",
          "Warmup"
        ]
      },
      "ExerciseType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Reps",
          "Time",
          "Distance",
          "DistanceWeight"
        ],
        "enum": [
          "Reps",
          "Time",
          "Distance",
          "DistanceWeight"
        ]
      },
      "Muscle": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Empty",
          "Abs",
          "Chest",
          "Back",
          "Biceps",
          "Glutes",
          "ShouldersFontDelt",
          "Triceps",
          "LowerBack",
          "Quads",
          "Hamstrings",
          "Calves",
          "Trapezius",
          "Abductors",
          "Forearms",
          "Neck",
          "Adductors"
        ],
        "enum": [
          "Empty",
          "Abs",
          "Chest",
          "Back",
          "Biceps",
          "Glutes",
          "ShouldersFontDelt",
          "Triceps",
          "LowerBack",
          "Quads",
          "Hamstrings",
          "Calves",
          "Trapezius",
          "Abductors",
          "Forearms",
          "Neck",
          "Adductors"
        ]
      },
      "Submuscle": {
        "type": "integer",
        "description": "",
        "x-enumNames": [
          "AbsRectus",
          "AbsObliques",
          "AbsTransverse",
          "ChestUpper",
          "ChestLower",
          "ChestMid",
          "BackDorsal",
          "BackRhomboids",
          "GlutesMaximus",
          "GlutesMedius",
          "GlutesUpper",
          "ShouldersRearDelts",
          "ShouldersFrontDelts",
          "ShouldersSideDelts",
          "QuadsRectusFemoris",
          "QuadsVasti"
        ],
        "enum": [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16
        ]
      },
      "PaginatedResponseOfPublicMeasurementDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicMeasurementDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicMeasurementDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "format": "guid"
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "weightUnit": {
            "$ref": "#/components/schemas/WeightUnit"
          },
          "weight": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bodyFat": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "neck": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "shoulder": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "chest": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bicep": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "forearm": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "abdomen": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "waist": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "glutes": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "thigh": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "calf": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        }
      },
      "WeightUnit": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Kilograms",
          "Pounds"
        ],
        "enum": [
          "Kilograms",
          "Pounds"
        ]
      },
      "PaginatedResponseOfPublicPersonalRecordDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicPersonalRecordDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicPersonalRecordDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "exerciseId": {
            "type": "integer",
            "format": "int32"
          },
          "exerciseName": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/PersonalRecordType"
          },
          "reps": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "weight": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "duration": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "distance": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "workoutId": {
            "type": "string",
            "format": "guid",
            "nullable": true
          },
          "achievedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PersonalRecordType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "OneRepMax",
          "WeightMax",
          "VolumeMax",
          "RepetitionMax",
          "DurationMax",
          "DistanceMax"
        ],
        "enum": [
          "OneRepMax",
          "WeightMax",
          "VolumeMax",
          "RepetitionMax",
          "DurationMax",
          "DistanceMax"
        ]
      },
      "PaginatedResponseOfPublicSplitDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSplitDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicSplitDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "format": "guid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "sessionCount": {
            "type": "integer",
            "format": "int32"
          },
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSplitSessionDto"
            }
          }
        }
      },
      "PublicSplitSessionDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "order": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/CustomSplitSessionType"
          },
          "muscles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "workoutTemplateId": {
            "type": "string",
            "format": "guid",
            "nullable": true
          }
        }
      },
      "CustomSplitSessionType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "WorkoutTemplate",
          "Muscles"
        ],
        "enum": [
          "WorkoutTemplate",
          "Muscles"
        ]
      },
      "PublicStatsDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "streak": {
            "$ref": "#/components/schemas/PublicStreakDto"
          },
          "totalXp": {
            "type": "integer",
            "format": "int32"
          },
          "trophyCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "PublicStreakDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "current": {
            "type": "integer",
            "format": "int32"
          },
          "longest": {
            "type": "integer",
            "format": "int32"
          },
          "workoutsThisWeek": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "PaginatedResponseOfPublicTrophyDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicTrophyDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicTrophyDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "type": {
            "$ref": "#/components/schemas/TrophyType"
          },
          "exerciseId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "exerciseName": {
            "type": "string",
            "nullable": true
          },
          "achievedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TrophyType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Workout1",
          "Workout5",
          "Workout10",
          "Workout50",
          "Workout100",
          "Streak1",
          "Streak5",
          "Streak10",
          "Streak20",
          "Streak35",
          "Streak50",
          "Calendar3",
          "Calendar4",
          "Calendar5",
          "Calendar6",
          "Calendar15",
          "Calendar20",
          "Calendar100",
          "Calendar200",
          "Workout200",
          "Kcal1000",
          "Kcal2000",
          "Kcal3000",
          "WorkoutMilestoneDropset",
          "WorkoutMilestoneFullBody",
          "WorkoutMilestoneCardio",
          "WorkoutMilestoneMaxEffort",
          "WorkoutMilestoneSuperset",
          "VolumeLifted5K",
          "VolumeLifted10K",
          "VolumeLifted20K",
          "VolumeLifted30K",
          "VolumeLifted100K",
          "VolumeLifted250K",
          "VolumeLifted1M",
          "VolumeLifted2M",
          "AppGymLocation",
          "AppAddFriend",
          "AppCustomWorkout",
          "AppEmptyWorkout",
          "AddMeasurement",
          "AppBigGoran",
          "AppFavouriteWorkout",
          "AppAddQueue",
          "AppShareWorkout",
          "Strength100",
          "Strength150",
          "Strength200",
          "Strength250",
          "ExerciseDifferent10",
          "ExerciseDifferent25",
          "ExerciseDifferent50",
          "ExerciseDifferent100",
          "ExerciseSame10",
          "ExerciseSame25",
          "ExerciseSame50"
        ],
        "enum": [
          "Workout1",
          "Workout5",
          "Workout10",
          "Workout50",
          "Workout100",
          "Streak1",
          "Streak5",
          "Streak10",
          "Streak20",
          "Streak35",
          "Streak50",
          "Calendar3",
          "Calendar4",
          "Calendar5",
          "Calendar6",
          "Calendar15",
          "Calendar20",
          "Calendar100",
          "Calendar200",
          "Workout200",
          "Kcal1000",
          "Kcal2000",
          "Kcal3000",
          "WorkoutMilestoneDropset",
          "WorkoutMilestoneFullBody",
          "WorkoutMilestoneCardio",
          "WorkoutMilestoneMaxEffort",
          "WorkoutMilestoneSuperset",
          "VolumeLifted5K",
          "VolumeLifted10K",
          "VolumeLifted20K",
          "VolumeLifted30K",
          "VolumeLifted100K",
          "VolumeLifted250K",
          "VolumeLifted1M",
          "VolumeLifted2M",
          "AppGymLocation",
          "AppAddFriend",
          "AppCustomWorkout",
          "AppEmptyWorkout",
          "AddMeasurement",
          "AppBigGoran",
          "AppFavouriteWorkout",
          "AppAddQueue",
          "AppShareWorkout",
          "Strength100",
          "Strength150",
          "Strength200",
          "Strength250",
          "ExerciseDifferent10",
          "ExerciseDifferent25",
          "ExerciseDifferent50",
          "ExerciseDifferent100",
          "ExerciseSame10",
          "ExerciseSame25",
          "ExerciseSame50"
        ]
      },
      "PublicUserDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "weightUnit": {
            "$ref": "#/components/schemas/WeightUnit"
          },
          "distanceUnit": {
            "$ref": "#/components/schemas/DistanceUnit"
          },
          "gender": {
            "nullable": true,
            "oneOf": [
              {
                "$ref": "#/components/schemas/Gender"
              }
            ]
          },
          "height": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "heightUnit": {
            "$ref": "#/components/schemas/HeightUnit"
          },
          "goal": {
            "nullable": true,
            "oneOf": [
              {
                "$ref": "#/components/schemas/Goal"
              }
            ]
          }
        }
      },
      "DistanceUnit": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Kilometers",
          "Miles"
        ],
        "enum": [
          "Kilometers",
          "Miles"
        ]
      },
      "Gender": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Male",
          "Female",
          "Other"
        ],
        "enum": [
          "Male",
          "Female",
          "Other"
        ]
      },
      "HeightUnit": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Centimeters",
          "FeetInches"
        ],
        "enum": [
          "Centimeters",
          "FeetInches"
        ]
      },
      "Goal": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Stronger",
          "MuscleMass",
          "Lean",
          "GeneralFitness"
        ],
        "enum": [
          "Stronger",
          "MuscleMass",
          "Lean",
          "GeneralFitness"
        ]
      },
      "PaginatedResponseOfPublicWorkoutSummaryDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicWorkoutSummaryDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicWorkoutSummaryDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "format": "guid"
          },
          "name": {
            "type": "string"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "durationMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/WorkoutType"
          },
          "volume": {
            "type": "number",
            "format": "double"
          },
          "calories": {
            "type": "number",
            "format": "double"
          },
          "personalRecordCount": {
            "type": "integer",
            "format": "int32"
          },
          "exerciseCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "WorkoutType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Today",
          "Custom",
          "Saved",
          "New",
          "Public",
          "External",
          "NewSaved"
        ],
        "enum": [
          "Today",
          "Custom",
          "Saved",
          "New",
          "Public",
          "External",
          "NewSaved"
        ]
      },
      "PublicWorkoutDetailDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "format": "guid"
          },
          "name": {
            "type": "string"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "durationMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/WorkoutType"
          },
          "volume": {
            "type": "number",
            "format": "double"
          },
          "calories": {
            "type": "number",
            "format": "double"
          },
          "personalRecordCount": {
            "type": "integer",
            "format": "int32"
          },
          "exercises": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicWorkoutExerciseDto"
            }
          }
        }
      },
      "PublicWorkoutExerciseDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "exerciseId": {
            "type": "integer",
            "format": "int32"
          },
          "exerciseName": {
            "type": "string"
          },
          "supersetId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSetDto"
            }
          }
        }
      },
      "PublicSetDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "order": {
            "type": "integer",
            "format": "int32"
          },
          "reps": {
            "type": "integer",
            "format": "int32"
          },
          "weight": {
            "type": "number",
            "format": "double"
          },
          "duration": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "distance": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "rpe": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "setType": {
            "$ref": "#/components/schemas/SetType"
          }
        }
      },
      "SetType": {
        "type": "string",
        "description": "",
        "x-enumNames": [
          "Normal",
          "Warmup",
          "DropSet",
          "Failure"
        ],
        "enum": [
          "Normal",
          "Warmup",
          "DropSet",
          "Failure"
        ]
      },
      "PaginatedResponseOfPublicWorkoutTemplateDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicWorkoutTemplateDto"
            }
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "PublicWorkoutTemplateDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "format": "guid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "exerciseCount": {
            "type": "integer",
            "format": "int32"
          },
          "exercises": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicTemplateExerciseDto"
            }
          }
        }
      },
      "PublicTemplateExerciseDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "exerciseId": {
            "type": "integer",
            "format": "int32"
          },
          "exerciseName": {
            "type": "string"
          },
          "supersetId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicTemplateSetDto"
            }
          }
        }
      },
      "PublicTemplateSetDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "order": {
            "type": "integer",
            "format": "int32"
          },
          "reps": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "weight": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "duration": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "distance": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "rpe": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "setType": {
            "$ref": "#/components/schemas/SetType"
          }
        }
      }
    },
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 authorization-code flow for apps acting on a user's behalf. Register an app and see https://gravl.ai/developers/oauth.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.gravl.ai/oauth/authorize",
            "tokenUrl": "https://api.gravl.ai/oauth/token",
            "refreshUrl": "https://api.gravl.ai/oauth/token",
            "scopes": {
              "profile:read": "See your profile (display name, username, units, goal)",
              "workouts:read": "Read your workout history and templates",
              "exercises:read": "Browse the exercise and equipment catalog",
              "records:read": "Read your personal records",
              "measurements:read": "Read your body measurements",
              "stats:read": "Read your streaks, XP and trophies",
              "splits:read": "Read your custom training splits"
            }
          }
        }
      },
      "personalToken": {
        "type": "http",
        "description": "Scoped personal access token, self-service for every Gravl account. Create one at https://gravl.ai/developers/personal-tokens.",
        "scheme": "bearer"
      }
    }
  },
  "security": [
    {
      "oauth2": []
    },
    {
      "personalToken": []
    }
  ]
}