{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://labfytools.com/trainlog/schema/trainlog-v1.schema.json", "title": "Trainlog Exchange Format v1", "type": "object", "additionalProperties": false, "required": [ "format", "version", "exercises", "session" ], "properties": { "format": { "const": "trainlog" }, "version": { "const": 1 }, "exercises": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/$defs/exerciseCatalogEntry" } }, "session": { "$ref": "#/$defs/session" } }, "$defs": { "exerciseId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9_-]*$" }, "sessionId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]*$" }, "note": { "type": "string", "minLength": 1, "maxLength": 4000 }, "exerciseCatalogEntry": { "type": "object", "additionalProperties": false, "required": [ "exercise_id", "name", "tracking_mode" ], "properties": { "exercise_id": { "$ref": "#/$defs/exerciseId" }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "tracking_mode": { "type": "string", "enum": [ "reps", "duration" ] } } }, "actualSet": { "type": "object", "additionalProperties": false, "properties": { "reps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "duration_seconds": { "type": "integer", "minimum": 1, "maximum": 86400 }, "weight_kg": { "type": "number", "exclusiveMinimum": 0, "maximum": 5000 } }, "oneOf": [ { "required": [ "reps" ], "not": { "required": [ "duration_seconds" ] } }, { "required": [ "duration_seconds" ], "not": { "required": [ "reps" ] } } ] }, "target": { "type": "object", "additionalProperties": false, "required": [ "sets" ], "properties": { "sets": { "type": "integer", "minimum": 1, "maximum": 1000 }, "reps": { "type": "integer", "minimum": 1, "maximum": 10000 }, "duration_seconds": { "type": "integer", "minimum": 1, "maximum": 86400 }, "weight_kg": { "type": "number", "exclusiveMinimum": 0, "maximum": 5000 } }, "oneOf": [ { "required": [ "reps" ], "not": { "required": [ "duration_seconds" ] } }, { "required": [ "duration_seconds" ], "not": { "required": [ "reps" ] } } ] }, "sessionExercise": { "type": "object", "additionalProperties": false, "required": [ "exercise_id", "load_mode", "rest_seconds", "target", "sets" ], "properties": { "exercise_id": { "$ref": "#/$defs/exerciseId" }, "load_mode": { "type": "string", "enum": [ "none", "external", "assistance" ] }, "rest_seconds": { "type": "integer", "minimum": 0, "maximum": 86400 }, "target": { "$ref": "#/$defs/target" }, "sets": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/$defs/actualSet" } }, "notes": { "type": "string", "minLength": 1, "maxLength": 1000 } } }, "measurements": { "type": "object", "additionalProperties": false, "minProperties": 1, "properties": { "neck_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "shoulders_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "chest_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "waist_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "hips_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "left_arm_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "right_arm_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "left_forearm_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "right_forearm_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "left_thigh_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "right_thigh_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "left_calf_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 }, "right_calf_cm": { "type": "number", "exclusiveMinimum": 0, "maximum": 500 } } }, "session": { "type": "object", "additionalProperties": false, "required": [ "session_id", "started_at", "exercises" ], "properties": { "session_id": { "$ref": "#/$defs/sessionId" }, "started_at": { "type": "string", "format": "date-time" }, "ended_at": { "type": "string", "format": "date-time" }, "body_weight_kg": { "type": "number", "exclusiveMinimum": 0, "maximum": 1000 }, "measurements": { "$ref": "#/$defs/measurements" }, "notes": { "$ref": "#/$defs/note" }, "exercises": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/$defs/sessionExercise" } } } } } }