{"openapi":"3.1.0","info":{"title":"Turtle Fit API","version":"1.0.0","description":"JSON API for Turtle Fit accounts, exercises, routines, and workouts."},"servers":[{"url":"/api"}],"paths":{"/account":{"get":{"summary":"Get the current account","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"},"example":{"id":"0aef8e0b-3782-41b9-96dd-fd792f3f45e2","name":"Alex","email":"alex@example.com","keepAlive":true,"restSeconds":120,"setSeconds":120,"healthkitAtMs":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}},"patch":{"summary":"Update the current account","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPatch"},"example":{"name":"Alex","restSeconds":90}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"},"example":{"id":"0aef8e0b-3782-41b9-96dd-fd792f3f45e2","name":"Alex","email":"alex@example.com","keepAlive":true,"restSeconds":120,"setSeconds":120,"healthkitAtMs":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/areas":{"get":{"summary":"List exercise areas","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Area"}},"example":[{"name":"core","title":"core","workouts":3,"lastAtMs":1705314600000}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}}},"/areas/{name}":{"get":{"summary":"List workouts for an exercise area","security":[{"bearerAuth":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AreaWorkout"}},"example":[{"id":"5d3862d1-6a1d-42db-a975-423307276a18","createdAtMs":1705314600000,"lastAtMs":1705314600000,"summary":"12 Suitcase Carries"}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}}},"/auth/login":{"post":{"summary":"Log in","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"},"example":{"email":"alex@example.com","password":"correct-horse-battery-staple"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"},"example":{"token":"session-token","user":{"id":"0aef8e0b-3782-41b9-96dd-fd792f3f45e2","name":"Alex","email":"alex@example.com","keepAlive":true,"restSeconds":120,"setSeconds":120,"healthkitAtMs":null}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/auth/signup":{"post":{"summary":"Sign up","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"},"example":{"email":"alex@example.com","password":"correct-horse-battery-staple"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"},"example":{"token":"session-token","user":{"id":"0aef8e0b-3782-41b9-96dd-fd792f3f45e2","name":"Alex","email":"alex@example.com","keepAlive":true,"restSeconds":120,"setSeconds":120,"healthkitAtMs":null}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"},"example":{"token":"session-token","user":{"id":"0aef8e0b-3782-41b9-96dd-fd792f3f45e2","name":"Alex","email":"alex@example.com","keepAlive":true,"restSeconds":120,"setSeconds":120,"healthkitAtMs":null}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/exercises":{"get":{"summary":"List exercises","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Exercise"}},"example":[{"id":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null,"favorite":true,"equipment":[{"id":"7ab8fca7-03e4-43ec-a011-66154bfa5348","name":"Dumbbell"}]}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}},"post":{"summary":"Create a custom exercise","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExerciseInput"},"example":{"name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Exercise"},"example":{"id":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null,"favorite":true,"equipment":[{"id":"7ab8fca7-03e4-43ec-a011-66154bfa5348","name":"Dumbbell"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/equipment":{"get":{"summary":"List equipment","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Equipment"}},"example":[{"id":"7ab8fca7-03e4-43ec-a011-66154bfa5348","name":"Dumbbell"}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}}},"/exercises/import":{"post":{"summary":"Import custom exercises in bulk","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExerciseImport"},"example":{"exercises":[{"name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null},{"name":"Farmer Carry","count":"rep","area":"full body","split":"other","videoUrl":null}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExerciseImportResponse"},"example":{"exercises":[{"status":"existing","exercise":{"id":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null,"favorite":true,"equipment":[{"id":"7ab8fca7-03e4-43ec-a011-66154bfa5348","name":"Dumbbell"}]}}]}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExerciseImportResponse"},"example":{"exercises":[{"status":"created","exercise":{"id":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","name":"Suitcase Carry","count":"rep","area":"full body","split":"other","videoUrl":null,"favorite":true,"equipment":[{"id":"7ab8fca7-03e4-43ec-a011-66154bfa5348","name":"Dumbbell"}]}}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexedValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"workouts":["Too small"]},"issues":[{"path":["workouts",0,"activities",0,"number"],"message":"Too small: expected number to be >=0"}]}}}}}}}},"/exercises/{id}/favorite":{"put":{"summary":"Favorite an exercise","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Favorite"},"example":{"favorite":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Exercise not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"exercise not found"}}}}}},"delete":{"summary":"Unfavorite an exercise","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Favorite"},"example":{"favorite":false}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Exercise not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"exercise not found"}}}}}}},"/health":{"get":{"summary":"Check service health","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"example":{"ok":true,"service":"fit-server"}}}}}}},"/history/exercises/{id}":{"get":{"summary":"Get exercise history","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExerciseHistory"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Exercise not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"exercise not found"}}}}}}},"/gyms":{"get":{"summary":"List the current user's gyms","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Gym"}},"example":[{"id":"4f75bb3e-4626-47de-866f-8904b76ad789","name":"Downtown YMCA"}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}},"post":{"summary":"Create a gym","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GymInput"},"example":{"name":"Downtown YMCA"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Gym"},"example":{"id":"4f75bb3e-4626-47de-866f-8904b76ad789","name":"Downtown YMCA"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/gyms/{id}":{"delete":{"summary":"Delete a gym","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Gym not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"gym not found"}}}}}}},"/leaders":{"get":{"summary":"List leaderboard entries","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Leader"}},"example":[{"user":{"name":"Alex","isViewer":true},"score":10,"workouts":1}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}}},"/routines":{"get":{"summary":"List routines","security":[{"bearerAuth":[]}],"parameters":[{"name":"filter","in":"query","schema":{"type":"string","enum":["used"]}},{"name":"scope","in":"query","schema":{"type":"string","enum":["all"]}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Routine"}},"example":[{"id":"9d285ce4-ce45-4e09-b549-76e78772f23d","createdAtMs":1705314600000,"name":"Strength","sets":[{"id":"81e6586a-4d48-44e6-9d6d-61e882b3c4c3","items":[{"id":"052dc29a-3849-48db-8935-f0880c75b4e7","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","quantities":[{"number":12,"weight":20,"units":"lbs"}]}]}]}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}},"post":{"summary":"Create a routine","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineInput"},"example":{"name":"Strength","sets":[{"items":[{"exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","quantities":[{"number":12,"weight":20,"units":"lbs"}]}]}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Routine"},"example":{"id":"9d285ce4-ce45-4e09-b549-76e78772f23d","createdAtMs":1705314600000,"name":"Strength","sets":[{"id":"81e6586a-4d48-44e6-9d6d-61e882b3c4c3","items":[{"id":"052dc29a-3849-48db-8935-f0880c75b4e7","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","quantities":[{"number":12,"weight":20,"units":"lbs"}]}]}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}}},"/routines/{id}":{"put":{"summary":"Replace a routine","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineInput"},"example":{"name":"Strength","sets":[]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Routine"},"example":{"id":"9d285ce4-ce45-4e09-b549-76e78772f23d","createdAtMs":1705314600000,"name":"Strength","sets":[{"id":"81e6586a-4d48-44e6-9d6d-61e882b3c4c3","items":[{"id":"052dc29a-3849-48db-8935-f0880c75b4e7","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","quantities":[{"number":12,"weight":20,"units":"lbs"}]}]}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Routine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"routine not found"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}},"delete":{"summary":"Delete a routine","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Routine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"routine not found"}}}}}}},"/workouts":{"get":{"summary":"List workouts","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Workout"}},"example":[{"id":"5d3862d1-6a1d-42db-a975-423307276a18","routineId":null,"summary":"12 Suitcase Carries","createdAtMs":1705314600000,"lastAtMs":1705314600000,"healthkitUuid":null,"activities":[{"id":"8feaa928-4a3f-4550-954f-10d53b5080cf","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}]}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}}}},"post":{"summary":"Create a workout","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutInput"},"example":{"createdAt":"2024-01-15T10:30:00.000Z","activities":[{"exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workout"},"example":{"id":"5d3862d1-6a1d-42db-a975-423307276a18","routineId":null,"summary":"12 Suitcase Carries","createdAtMs":1705314600000,"lastAtMs":1705314600000,"healthkitUuid":null,"activities":[{"id":"8feaa928-4a3f-4550-954f-10d53b5080cf","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexedValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"workouts":["Too small"]},"issues":[{"path":["workouts",0,"activities",0,"number"],"message":"Too small: expected number to be >=0"}]}}}}}}}},"/workouts/import":{"post":{"summary":"Import historical workouts in bulk","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutImport"},"example":{"workouts":[{"createdAt":"2024-01-15T10:30:00.000Z","activities":[{"exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]},{"createdAt":"2024-01-14T09:00:00.000Z","activities":[{"exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":10,"weight":20,"units":"lbs","completedAt":"2024-01-14T09:00:00.000Z"}]}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["workouts"],"properties":{"workouts":{"type":"array","items":{"$ref":"#/components/schemas/Workout"}}}},"example":{"workouts":[{"id":"5d3862d1-6a1d-42db-a975-423307276a18","routineId":null,"summary":"12 Suitcase Carries","createdAtMs":1705314600000,"lastAtMs":1705314600000,"healthkitUuid":null,"activities":[{"id":"8feaa928-4a3f-4550-954f-10d53b5080cf","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexedValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"workouts":["Too small"]},"issues":[{"path":["workouts",0,"activities",0,"number"],"message":"Too small: expected number to be >=0"}]}}}}}}}},"/workouts/{id}":{"get":{"summary":"Get a workout","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workout"},"example":{"id":"5d3862d1-6a1d-42db-a975-423307276a18","routineId":null,"summary":"12 Suitcase Carries","createdAtMs":1705314600000,"lastAtMs":1705314600000,"healthkitUuid":null,"activities":[{"id":"8feaa928-4a3f-4550-954f-10d53b5080cf","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Workout not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"workout not found"}}}}}},"patch":{"summary":"Update a workout","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutUpdate"},"example":{"healthkitUuid":"B891C1D4-44D0-4D78-A669-0997C92A4C32"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workout"},"example":{"id":"5d3862d1-6a1d-42db-a975-423307276a18","routineId":null,"summary":"12 Suitcase Carries","createdAtMs":1705314600000,"lastAtMs":1705314600000,"healthkitUuid":null,"activities":[{"id":"8feaa928-4a3f-4550-954f-10d53b5080cf","exerciseId":"1e5df6a2-6867-42af-a5a0-9802ffce7d86","number":12,"weight":20,"units":"lbs","completedAt":"2024-01-15T10:30:00.000Z"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Workout not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"workout not found"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"example":{"errors":{"formErrors":[],"fieldErrors":{"email":["Invalid email address"]}}}}}}}},"delete":{"summary":"Delete a workout","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationError"},"example":{"error":"authentication required"}}}},"404":{"description":"Workout not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"},"example":{"error":"workout not found"}}}}}}},"/openapi.json":{"get":{"summary":"Get the OpenAPI document","responses":{"200":{"description":"OpenAPI 3.1 JSON document","content":{"application/json":{"schema":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"type":"string"},"info":{"type":"object"},"paths":{"type":"object"}}},"example":{"openapi":"3.1.0","info":{"title":"Turtle Fit API","version":"1.0.0"},"paths":{}}}}}}}},"/docs":{"get":{"summary":"Get the HTML API reference","responses":{"200":{"description":"HTML API reference","content":{"text/html":{"schema":{"type":"string","contentMediaType":"text/html"},"example":"<!doctype html><html lang=\"en\"><head><title>Turtle Fit API</title></head><body>…</body></html>"}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Account":{"type":"object","required":["id","name","email","keepAlive","restSeconds","setSeconds","healthkitAtMs"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"keepAlive":{"type":"boolean"},"restSeconds":{"type":"integer"},"setSeconds":{"type":"integer"},"healthkitAtMs":{"type":["integer","null"]}}},"AccountPatch":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"keepAlive":{"type":"boolean"},"restSeconds":{"type":"integer","minimum":0,"maximum":3600},"setSeconds":{"type":"integer","minimum":0,"maximum":3600},"healthkitAtMs":{"type":["integer","null"]}}},"Activity":{"type":"object","required":["id","exerciseId","number","weight","units","completedAt"],"properties":{"id":{"type":"string","format":"uuid"},"exerciseId":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0},"weight":{"type":"integer","minimum":0},"units":{"type":"string","enum":["lbs"]},"completedAt":{"type":"string","format":"date-time"}}},"ActivityInput":{"type":"object","required":["exerciseId","number","units"],"properties":{"exerciseId":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0},"weight":{"type":"integer","minimum":0,"default":0},"units":{"type":"string","enum":["lbs"]},"completedAt":{"type":"string","format":"date-time","description":"ISO-8601 timestamp with a UTC offset, for example 2024-01-15T10:30:00.000Z."}}},"Area":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"workouts":{"type":"integer"},"lastAtMs":{"type":["integer","null"]}}},"AreaWorkout":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"createdAtMs":{"type":"integer"},"lastAtMs":{"type":"integer"},"summary":{"type":"string"}}},"AuthenticationError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","example":"authentication required"}}},"AuthResponse":{"type":"object","required":["token","user"],"properties":{"token":{"type":"string"},"user":{"$ref":"#/components/schemas/Account"}}},"Credentials":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8,"format":"password"}}},"Equipment":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"Exercise":{"type":"object","required":["id","name","count","area","split","videoUrl","favorite","equipment"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"count":{"type":"string","enum":["rep","timed"]},"area":{"type":"string","enum":["back","arms","chest","shoulder","butt","core","legs","full body","custom"]},"split":{"type":"string","enum":["push","pull","legs","other"]},"videoUrl":{"type":["string","null"],"format":"uri"},"favorite":{"type":"boolean"},"equipment":{"type":"array","items":{"$ref":"#/components/schemas/Equipment"}}}},"ExerciseImport":{"type":"object","additionalProperties":false,"required":["exercises"],"properties":{"exercises":{"type":"array","minItems":1,"maxItems":500,"items":{"$ref":"#/components/schemas/ExerciseInput"}}}},"ExerciseImportResponse":{"type":"object","required":["exercises"],"properties":{"exercises":{"type":"array","items":{"type":"object","required":["status","exercise"],"properties":{"status":{"type":"string","enum":["created","existing"]},"exercise":{"$ref":"#/components/schemas/Exercise"}}}}}},"ExerciseInput":{"type":"object","required":["name","count","area","split"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"count":{"type":"string","enum":["rep","timed"]},"area":{"type":"string","enum":["back","arms","chest","shoulder","butt","core","legs","full body","custom"]},"split":{"type":"string","enum":["push","pull","legs","other"]},"videoUrl":{"type":["string","null"],"format":"uri"}}},"ExerciseHistory":{"type":"object","properties":{"exercise":{"type":"object"},"lastAtMs":{"type":["integer","null"]},"bestSummary":{"type":"string","description":"All-time best 1RM, or an explicit rep/duration summary."},"ninetyDayBestSummary":{"type":"string","description":"Best performance within the last 90 days."},"exerciseSummary":{"type":"string","description":"Most recent workout performance."},"lineChart":{"type":"object","properties":{"unit":{"type":"string","enum":["lb","reps","sec"]}}},"workouts":{"type":"array","items":{"$ref":"#/components/schemas/HistoryWorkout"}}}},"HistorySet":{"type":"object","required":["number","weight"],"properties":{"number":{"type":"integer","minimum":0},"weight":{"type":"integer","minimum":0}}},"HistoryWorkout":{"type":"object","required":["id","createdAtMs","exerciseSummary","sets"],"properties":{"id":{"type":"string","format":"uuid"},"createdAtMs":{"type":"integer"},"exerciseSummary":{"type":"string"},"sets":{"type":"array","items":{"$ref":"#/components/schemas/HistorySet"}}}},"Favorite":{"type":"object","required":["favorite"],"properties":{"favorite":{"type":"boolean"}}},"Health":{"type":"object","required":["ok","service"],"properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}},"Gym":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"GymInput":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100}}},"Leader":{"type":"object","required":["user","score","workouts"],"properties":{"user":{"type":"object","required":["name","isViewer"],"properties":{"name":{"type":"string"},"isViewer":{"type":"boolean","description":"True for the authenticated caller's own row. Other users are never identified by id."}}},"score":{"type":"integer"},"workouts":{"type":"integer"}}},"NotFoundError":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"Routine":{"type":"object","required":["id","name","sets"],"properties":{"id":{"type":"string","format":"uuid"},"createdAtMs":{"type":"integer"},"name":{"type":"string"},"canEdit":{"type":"boolean","description":"Included when scope=all; true when the authenticated caller may edit the routine."},"sets":{"type":"array","items":{"$ref":"#/components/schemas/RoutineSet"}}}},"RoutineItem":{"type":"object","required":["id","exerciseId","quantities"],"properties":{"id":{"type":"string","format":"uuid"},"exerciseId":{"type":"string","format":"uuid"},"quantities":{"type":"array","items":{"$ref":"#/components/schemas/RoutineQuantity"}}}},"RoutineItemInput":{"type":"object","required":["exerciseId","quantities"],"properties":{"exerciseId":{"type":"string","format":"uuid"},"quantities":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/RoutineQuantity"}}}},"RoutineQuantity":{"type":"object","required":["number","weight"],"properties":{"number":{"type":"integer","minimum":0},"weight":{"type":"integer","minimum":0},"units":{"type":"string","enum":["lbs"]}}},"RoutineSet":{"type":"object","required":["id","items"],"properties":{"id":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/RoutineItem"}}}},"RoutineSetInput":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RoutineItemInput"}}}},"RoutineInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"sets":{"type":"array","items":{"$ref":"#/components/schemas/RoutineSetInput"}}}},"ValidationError":{"type":"object","required":["errors"],"properties":{"errors":{"oneOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/components/schemas/ValidationErrors"}]}}},"ValidationErrors":{"type":"object","required":["formErrors","fieldErrors"],"properties":{"formErrors":{"type":"array","items":{"type":"string"}},"fieldErrors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"issues":{"type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}}}},"IndexedValidationError":{"type":"object","required":["errors"],"properties":{"errors":{"$ref":"#/components/schemas/IndexedValidationErrors"}}},"IndexedValidationErrors":{"type":"object","required":["formErrors","fieldErrors","issues"],"properties":{"formErrors":{"type":"array","items":{"type":"string"}},"fieldErrors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"issues":{"type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}}}},"ValidationIssue":{"type":"object","required":["path","message"],"properties":{"path":{"type":"array","items":{"type":["string","integer"]},"description":"Exact request location, including array indexes."},"message":{"type":"string"}}},"Workout":{"type":"object","required":["id","routineId","summary","createdAtMs","lastAtMs","healthkitUuid","activities"],"properties":{"id":{"type":"string","format":"uuid"},"routineId":{"type":["string","null"],"format":"uuid"},"summary":{"type":"string"},"createdAtMs":{"type":"integer"},"lastAtMs":{"type":"integer"},"healthkitUuid":{"type":["string","null"]},"activities":{"type":"array","items":{"$ref":"#/components/schemas/Activity"}}}},"WorkoutImport":{"type":"object","additionalProperties":false,"required":["workouts"],"properties":{"workouts":{"type":"array","minItems":1,"maxItems":500,"items":{"$ref":"#/components/schemas/WorkoutInput"}}}},"WorkoutInput":{"type":"object","additionalProperties":false,"properties":{"routineId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 timestamp with a UTC offset, for example 2024-01-15T10:30:00.000Z."},"activities":{"type":"array","items":{"$ref":"#/components/schemas/ActivityInput"}}}},"WorkoutUpdate":{"type":"object","additionalProperties":false,"properties":{"routineId":{"type":["string","null"],"format":"uuid"},"healthkitUuid":{"type":["string","null"],"maxLength":200},"activities":{"type":"array","items":{"$ref":"#/components/schemas/ActivityInput"}}}}}}}