The KERN API uses two layers of data models: Pydantic models for request validation and response serialization (defined inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/jaimegayo/KERNDOCUMENTATION/llms.txt
Use this file to discover all available pages before exploring further.
app.py and models.py), and SQLAlchemy models for database persistence (defined in models.py).
Pydantic request models
These models validate inbound request bodies. Fields marked optional default toNone unless a different default is specified.
UserCreate
Used byPOST /register.
Unique display name. Stored in
users.username (max 128 chars, unique index).Email address. Stored in
users.email (max 255 chars, unique index).Plain-text password. Hashed with SHA-256 before storage. Never persisted in plain text.
User’s full name. Optional. Stored in
users.full_name (max 100 chars).Phone number. Optional. Stored in
users.phone (max 50 chars).LoginRequest
Used byPOST /login.
The registered email address.
Plain-text password. The API hashes it and compares with the stored hash.
QuizCompletion
Used byPOST /users/complete-quiz.
The training plan chosen by the user. One of:
"Full Body", "PPL (Push Pull Leg)", "Torso-Pierna".AvatarUpdate
Used byPUT /users/avatar.
Public URL of the new avatar image.
UsernameUpdate
Used byPUT /users/update_name.
The desired new username. Must not be taken by another account.
WorkoutSessionCreate
Used byPOST /workouts/finish.
Name of the routine that was performed.
Session duration in seconds.
Total volume (kg) calculated as sum of kilos × reps for all sets.
Steps recorded during the session by the Android StepCounterService.
Full snapshot of all exercises and sets performed. Stored verbatim in the
workout_sessions.data_json JSON column.RoutineCreate
Used byPOST /routines/create and PUT /routines/{routine_id}.
ID of the authenticated user who owns the routine.
Routine display name.
List of exercises to include. Each item uses the
RoutineExerciseCreate schema.SerieCreate
Nested withinRoutineCreate.ejercicios[].series.
Set number, starting at 1.
Weight in kilograms. Use
0 as the initial placeholder.Target or actual repetitions.
Pydantic response models
These models shape the JSON returned by the API.LoginResponse
Returned byPOST /register, POST /login, and PUT /users/update_name.
Signed JWT token (HS256). Valid for 30 minutes. Field name is
accessToken (camelCase) due to a Pydantic Field(alias="accessToken") on the underlying access_token attribute.Always
"bearer".The authenticated user’s data. See
UserData below.UserData
Returned as theuser field in LoginResponse and directly by all /users/me, /users/avatar, and /users/complete-quiz endpoints.
Auto-incremented user ID.
Display name.
Email address.
Full name.
null if not set.Phone number.
null if not set.Avatar image URL.
null if not set.Account role.
Short biography.
null if not set.Whether the onboarding quiz has been completed.
Routine type selected during the quiz.
null until the quiz is completed.ISO 8601 account creation timestamp.
Whether the account is disabled.
UserStats
Returned byGET /users/stats.
Total number of completed workout sessions.
Sum of all steps across all sessions.
Unique calendar dates (
"YYYY-MM-DD") with at least one recorded session.Exercise
Returned by all/exercises/* endpoints. Defined in app.py (not models.py) as a Pydantic model that validates data loaded from JSON files.
Unique exercise ID within its JSON catalog file.
Exercise name. This is the canonical key used to match exercises between the routine and workout session data.
Primary muscle group (e.g.,
"Pecho", "Espalda", "Cuádriceps").Movement category (e.g.,
"Empuje horizontal", "Tracción vertical"). Used by the auto-routine generator.Equipment required.
Full execution instructions.
Coaching cues.
Common errors to avoid.
Optional demonstration video URL.
null if unavailable.SQLAlchemy database models
These are the ORM classes inmodels.py that map to database tables. The database is managed by SQLAlchemy with async support via AsyncSession.
User — table: users
Primary key. Auto-incremented.
Unique, indexed. The JWT
sub claim is set to this value.Unique, indexed.
SHA-256 hex digest. Never returned by any API endpoint.
Nullable.
Nullable.
Nullable.
Account role.
Nullable.
Set to
true by POST /users/complete-quiz.Nullable. Set by
POST /users/complete-quiz.When
true, all authenticated requests return 400 Usuario inactivo.Server-side default via
func.now().Routine — table: routines
Primary key. Auto-incremented.
Foreign key →
users.id. Not nullable.Routine display name. Not nullable.
Server-side default via
func.now().owner→User(many-to-one)exercises→RoutineExercise[](one-to-many,cascade="all, delete-orphan")
RoutineExercise — table: routine_exercises
Primary key. Auto-incremented.
Foreign key →
routines.id.Exercise name as a denormalized string. Must match the catalog
name for instruction lookups.Array of set objects (
[{numSerie, kilos, reps}]) stored as a JSON column. Not nullable.routine→Routine(many-to-one)
WorkoutSession — table: workout_sessions
Primary key. Auto-incremented.
Foreign key →
users.id. Not nullable.Name of the routine performed. Used for case-insensitive matching in the progression query.
Session duration. Not nullable.
Total training volume in kg.
Steps recorded during the session.
Full exercise + series snapshot. Read back by
GET /routines/{id} to populate progression fields.Server-side default via
func.now(). Used for ordering history and deduplicating training_days.owner→User(many-to-one)