JSON API for Turtle Fit accounts, exercises, routines, and workouts.
GET /api/accountGet the current account
Bearer authentication required
application/json
{
"id": "0aef8e0b-3782-41b9-96dd-fd792f3f45e2",
"name": "Alex",
"email": "alex@example.com",
"keepAlive": true,
"restSeconds": 120,
"setSeconds": 120,
"healthkitAtMs": null
}application/json
{
"error": "authentication required"
}PATCH /api/accountUpdate the current account
Bearer authentication required
{
"name": "Alex",
"restSeconds": 90
}application/json
{
"id": "0aef8e0b-3782-41b9-96dd-fd792f3f45e2",
"name": "Alex",
"email": "alex@example.com",
"keepAlive": true,
"restSeconds": 120,
"setSeconds": 120,
"healthkitAtMs": null
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}GET /api/areasList exercise areas
Bearer authentication required
application/json
[
{
"name": "core",
"title": "core",
"workouts": 3,
"lastAtMs": 1705314600000
}
]application/json
{
"error": "authentication required"
}GET /api/areas/{name}List workouts for an exercise area
Bearer authentication required
application/json
[
{
"id": "5d3862d1-6a1d-42db-a975-423307276a18",
"createdAtMs": 1705314600000,
"lastAtMs": 1705314600000,
"summary": "12 Suitcase Carries"
}
]application/json
{
"error": "authentication required"
}POST /api/auth/loginLog in
Public endpoint
{
"email": "alex@example.com",
"password": "correct-horse-battery-staple"
}application/json
{
"token": "session-token",
"user": {
"id": "0aef8e0b-3782-41b9-96dd-fd792f3f45e2",
"name": "Alex",
"email": "alex@example.com",
"keepAlive": true,
"restSeconds": 120,
"setSeconds": 120,
"healthkitAtMs": null
}
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}POST /api/auth/signupSign up
Public endpoint
{
"email": "alex@example.com",
"password": "correct-horse-battery-staple"
}application/json
{
"token": "session-token",
"user": {
"id": "0aef8e0b-3782-41b9-96dd-fd792f3f45e2",
"name": "Alex",
"email": "alex@example.com",
"keepAlive": true,
"restSeconds": 120,
"setSeconds": 120,
"healthkitAtMs": null
}
}application/json
{
"token": "session-token",
"user": {
"id": "0aef8e0b-3782-41b9-96dd-fd792f3f45e2",
"name": "Alex",
"email": "alex@example.com",
"keepAlive": true,
"restSeconds": 120,
"setSeconds": 120,
"healthkitAtMs": null
}
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}GET /api/exercisesList exercises
Bearer authentication required
q: {"type":"string"}application/json
[
{
"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"
}
]
}
]application/json
{
"error": "authentication required"
}POST /api/exercisesCreate a custom exercise
Bearer authentication required
{
"name": "Suitcase Carry",
"count": "rep",
"area": "full body",
"split": "other",
"videoUrl": null
}application/json
{
"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"
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}GET /api/equipmentList equipment
Bearer authentication required
application/json
[
{
"id": "7ab8fca7-03e4-43ec-a011-66154bfa5348",
"name": "Dumbbell"
}
]application/json
{
"error": "authentication required"
}POST /api/exercises/importImport custom exercises in bulk
Bearer authentication required
{
"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
}
]
}application/json
{
"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"
}
]
}
}
]
}application/json
{
"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"
}
]
}
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"workouts": [
"Too small"
]
},
"issues": [
{
"path": [
"workouts",
0,
"activities",
0,
"number"
],
"message": "Too small: expected number to be >=0"
}
]
}
}PUT /api/exercises/{id}/favoriteFavorite an exercise
Bearer authentication required
application/json
{
"favorite": true
}application/json
{
"error": "authentication required"
}application/json
{
"error": "exercise not found"
}DELETE /api/exercises/{id}/favoriteUnfavorite an exercise
Bearer authentication required
application/json
{
"favorite": false
}application/json
{
"error": "authentication required"
}application/json
{
"error": "exercise not found"
}GET /api/healthCheck service health
Public endpoint
application/json
{
"ok": true,
"service": "fit-server"
}GET /api/history/exercises/{id}Get exercise history
Bearer authentication required
application/json
application/json
{
"error": "authentication required"
}application/json
{
"error": "exercise not found"
}GET /api/gymsList the current user's gyms
Bearer authentication required
application/json
[
{
"id": "4f75bb3e-4626-47de-866f-8904b76ad789",
"name": "Downtown YMCA"
}
]application/json
{
"error": "authentication required"
}POST /api/gymsCreate a gym
Bearer authentication required
{
"name": "Downtown YMCA"
}application/json
{
"id": "4f75bb3e-4626-47de-866f-8904b76ad789",
"name": "Downtown YMCA"
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}DELETE /api/gyms/{id}Delete a gym
Bearer authentication required
application/json
{
"error": "authentication required"
}application/json
{
"error": "gym not found"
}GET /api/leadersList leaderboard entries
Bearer authentication required
application/json
[
{
"user": {
"name": "Alex",
"isViewer": true
},
"score": 10,
"workouts": 1
}
]application/json
{
"error": "authentication required"
}GET /api/routinesList routines
Bearer authentication required
filter: {"type":"string","enum":["used"]}scope: {"type":"string","enum":["all"]}application/json
[
{
"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"
}
]
}
]
}
]
}
]application/json
{
"error": "authentication required"
}POST /api/routinesCreate a routine
Bearer authentication required
{
"name": "Strength",
"sets": [
{
"items": [
{
"exerciseId": "1e5df6a2-6867-42af-a5a0-9802ffce7d86",
"quantities": [
{
"number": 12,
"weight": 20,
"units": "lbs"
}
]
}
]
}
]
}application/json
{
"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"
}
]
}
]
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}PUT /api/routines/{id}Replace a routine
Bearer authentication required
{
"name": "Strength",
"sets": []
}application/json
{
"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"
}
]
}
]
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"error": "routine not found"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}DELETE /api/routines/{id}Delete a routine
Bearer authentication required
application/json
{
"error": "authentication required"
}application/json
{
"error": "routine not found"
}GET /api/workoutsList workouts
Bearer authentication required
application/json
[
{
"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"
}
]
}
]application/json
{
"error": "authentication required"
}POST /api/workoutsCreate a workout
Bearer authentication required
{
"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"
}
]
}application/json
{
"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"
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"workouts": [
"Too small"
]
},
"issues": [
{
"path": [
"workouts",
0,
"activities",
0,
"number"
],
"message": "Too small: expected number to be >=0"
}
]
}
}POST /api/workouts/importImport historical workouts in bulk
Bearer authentication required
{
"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"
}
]
}
]
}application/json
{
"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"
}
]
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"workouts": [
"Too small"
]
},
"issues": [
{
"path": [
"workouts",
0,
"activities",
0,
"number"
],
"message": "Too small: expected number to be >=0"
}
]
}
}GET /api/workouts/{id}Get a workout
Bearer authentication required
application/json
{
"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"
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"error": "workout not found"
}PATCH /api/workouts/{id}Update a workout
Bearer authentication required
{
"healthkitUuid": "B891C1D4-44D0-4D78-A669-0997C92A4C32"
}application/json
{
"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"
}
]
}application/json
{
"error": "authentication required"
}application/json
{
"error": "workout not found"
}application/json
{
"errors": {
"formErrors": [],
"fieldErrors": {
"email": [
"Invalid email address"
]
}
}
}DELETE /api/workouts/{id}Delete a workout
Bearer authentication required
application/json
{
"error": "authentication required"
}application/json
{
"error": "workout not found"
}GET /api/openapi.jsonGet the OpenAPI document
Public endpoint
application/json
{
"openapi": "3.1.0",
"info": {
"title": "Turtle Fit API",
"version": "1.0.0"
},
"paths": {}
}GET /api/docsGet the HTML API reference
Public endpoint
text/html
"<!doctype html><html lang=\"en\"><head><title>Turtle Fit API</title></head><body>…</body></html>"