Esquema de entrenamiento

Última actualización: 2026-05-29

Your Trainer es una app de ciclismo indoor para varios ciclistas en tabletas Android. Control de smart trainer con datos locales + control local. Compra única.

El archivo de entrenamiento .ytw es JSON sencillo — créalo en cualquier editor de texto, impórtalo mediante la hoja de compartir, compártelo con tus amigos. El editor visual cubre los casos comunes; el esquema es la salida cuando necesitas control total.

Cuándo crearlo a mano

La mayoría de los ciclistas nunca necesitan esta página — el editor visual de entrenamientos y el AI Workout Coach cubren todo, desde una sesión de umbral de 4×8 hasta una serie de microbursts. Recurre al esquema cuando:

Ejemplo mínimo

El archivo .ytw válido más corto es un programa con un Intervalo. Guárdalo con la extensión .ytw y compártelo con Your Trainer.

{
  "programId": "my-sweet-spot",
  "programName": "My Sweet Spot 30",
  "description": "A short sweet-spot workout.",
  "totalDuration": 1800,
  "workoutType": "POWER",
  "primaryLocale": "en",
  "intervals": [
    { "id": "warmup",   "duration": 300,  "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Warmup",     "intervalType": "WARMUP"   },
    { "id": "work",     "duration": 1200, "targetPowerPercent": 88, "intensityZone": "Z3", "label": "Sweet Spot", "intervalType": "INTERVAL" },
    { "id": "cooldown", "duration": 300,  "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Cooldown",   "intervalType": "COOLDOWN" }
  ]
}

Campos de nivel superior

El objeto de nivel superior describe un programa de entrenamiento. Los campos requeridos están marcados.

CampoTipoDescripción
programId requeridostringIdentificador estable. Usa kebab-case (my-sweet-spot). Es la clave única del entrenamiento en tu biblioteca — reimportar un archivo con el mismo programId actualiza la entrada existente en lugar de crear un duplicado.
programName requeridostringNombre visible en la configuración regional principal del ciclista.
description requeridostringDescripción de una o dos frases que se muestra en la tarjeta del entrenamiento.
totalDuration requeridoentero (segundos)Duración total del entrenamiento. La app la recalcula a partir de los Intervalos al guardar, así que es seguro dejarla inconsistente durante la creación.
intervals requeridoarrayLista ordenada de objetos de Intervalo o grupos de repetición.
workoutTypestringFamilia de entrenamiento: POWER (por defecto), HR_ZONE o ROUTE. Consulta Tipos de entrenamiento.
variantstringSub-forma dentro de la familia: STANDARD (por defecto) o RAMP_TEST.
primaryLocalestring (BCP-47)Configuración regional en la que se redactaron las cadenas. Por defecto "en". Determina la cadena de respaldo entre configuraciones regionales.
categorystringCategorización de texto libre (p. ej. "threshold", "endurance"). Opcional.
difficultyentero (1–5)Dificultad subjetiva. Aparece en la tarjeta del entrenamiento.
isUserCreatedbooleanTrue para los entrenamientos creados en la app por el ciclista; false para los entrenamientos importados o incluidos. Por defecto false.
isFavoritebooleanIndicador de fijado arriba. Los ciclistas lo activan dentro de la app; suele omitirse en los archivos compartidos.
routeProfilearray de { distanceMeters, elevationMeters }Perfil de elevación completo para los entrenamientos ROUTE. Null para POWER y HR_ZONE.
stringsobject (locale → LocaleStrings)Traducciones por configuración regional del nombre, la descripción, las etiquetas de Intervalo y las indicaciones.

Campos del Intervalo

Cada objeto de Intervalo describe un bloque del entrenamiento. La forma del bloque depende del workoutType del padre — los bloques Power usan porcentajes de potencia, los bloques HR-Zone usan un objetivo de Zona.

CampoTipoDescripción
duration requeridoentero (segundos)Duración del bloque en segundos.
targetPowerPercent power-requiredentero (% de FTP)Objetivo de potencia para los entrenamientos POWER. Mutuamente excluyente con targetHrZone.
targetPowerEndPercententero (% de FTP)Potencia final de rampa opcional. Cuando está presente, los Watts objetivo se interpolan linealmente desde targetPowerPercenttargetPowerEndPercent a lo largo del bloque.
targetHrZone hr-requiredentero (1–5)Zona de FC para los entrenamientos HR_ZONE. Mutuamente excluyente con targetPowerPercent.
intensityZone requeridostringToken visual de Zona: Z1Z5. Determina el color en la visualización del terreno. Consulta Zonas de entrenamiento.
intervalTypestringWARMUP, COOLDOWN o INTERVAL (por defecto). Los bloques de Calentamiento y Vuelta a la calma se excluyen de los resúmenes de solo trabajo (potencia media de los bloques de trabajo, tiempo en Zona en la parte de trabajo, etc.).
label requeridostringTexto visible en el bloque en la configuración regional principal del ciclista. Las variantes entre configuraciones regionales viven en strings.<locale>.labels.
idstringSlug estable — la clave usada en strings.<locale>.labels y en la composición de claves de indicaciones. Recomendado para cualquier entrenamiento que se distribuya con traducciones.
autoLabelbooleanTrue cuando la etiqueta fue generada por un preset del editor en lugar de ser escrita por el ciclista. Las etiquetas automáticas las localiza el propio Your Trainer y no necesitan entradas por configuración regional en strings. Por defecto false.
cadenceTargetentero (RPM)Objetivo de Cadencia opcional para el bloque (p. ej. 60 para subidas de Cadencia baja, 100 para ejercicios de spin-up).
cuesarray de CoachingCueIndicaciones de entrenador que se disparan durante el bloque.

Indicaciones de entrenador

Una indicación de entrenador es una superposición breve de texto que aparece en la cabina durante una sesión. Cada indicación tiene un desplazamiento dentro de su Intervalo padre, el texto a mostrar y cuánto tiempo dejarla en pantalla.

CampoTipoDescripción
offsetSec requeridoentero (segundos)Segundos desde el inicio del Intervalo padre en los que se dispara la indicación.
text requeridostringTexto de la indicación en la configuración regional principal del entrenamiento. Las variantes entre configuraciones regionales viven en strings.<locale>.cues, indexadas por <intervalId>:<cueIndex>.
durationSecentero (segundos)Cuánto tiempo permanece la indicación en pantalla. Por defecto 5.

Ejemplo de Intervalo con tres indicaciones (la composición de la clave usa el id del Intervalo padre + el índice de la indicación en el array):

{
  "id": "work",
  "duration": 600,
  "targetPowerPercent": 95,
  "intensityZone": "Z4",
  "label": "Threshold",
  "intervalType": "INTERVAL",
  "cues": [
    { "offsetSec": 0,   "text": "Settle in — find your rhythm." },
    { "offsetSec": 300, "text": "Halfway. Stay smooth.",  "durationSec": 8 },
    { "offsetSec": 540, "text": "One minute. Hold form." }
  ]
}

Cadenas localizadas y cadena de respaldo

El bloque strings contiene las traducciones por configuración regional de cada cadena visible para el ciclista en el entrenamiento. Cada entrada de configuración regional tiene la misma forma:

"strings": {
  "en": {
    "name": "Sweet Spot 30",
    "description": "A short sweet-spot workout.",
    "labels": { "warmup": "Warmup", "work": "Sweet Spot", "cooldown": "Cooldown" },
    "cues":   { "work:0": "Settle in", "work:1": "Halfway" }
  },
  "de": {
    "name": "Sweet Spot 30",
    "description": "Ein kurzes Sweet-Spot-Training.",
    "labels": { "warmup": "Aufwärmen", "work": "Sweet Spot", "cooldown": "Ausrollen" },
    "cues":   { "work:0": "Locker einrollen", "work:1": "Halbzeit" }
  }
}

Las claves de indicaciones siguen el patrón <intervalId>:<cueIndex> — así, la primera indicación del Intervalo work tiene la clave work:0.

Para cada cadena visible para el ciclista, la app elige la mejor coincidencia de configuración regional en este orden:

  1. strings[<rider-locale>] — la configuración regional propia del ciclista.
  2. strings[primaryLocale] — la configuración regional del autor.
  3. strings["en"] — respaldo universal.
  4. El campo de nivel superior (programName, label del Intervalo, text de la indicación).

Las cadenas mostradas desde cualquier configuración regional distinta de la propia del ciclista aparecen en cursiva en las tarjetas de entrenamiento y en la cabina, para que el ciclista pueda ver qué cadenas aún no se han traducido.

See also: Habilidades de prompts de IA — the AI Coach can generate strings blocks for additional locales when prompted.

Grupos de repetición

Para las estructuras repetitivas, un grupo de repetición crea la unidad una vez y le indica a la app cuántas veces reproducirla. Los grupos de repetición se expanden en bloques individuales al importarlos, por lo que el ciclista ve cada bloque en la tira de próximos Intervalos durante la sesión.

{
  "intervals": [
    { "id": "warmup", "duration": 600, "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Warmup", "intervalType": "WARMUP" },
    {
      "repeat": 4,
      "intervals": [
        { "id": "on",  "duration": 480, "targetPowerPercent": 95, "intensityZone": "Z4", "label": "Threshold" },
        { "id": "off", "duration": 240, "targetPowerPercent": 55, "intensityZone": "Z1", "label": "Recovery" }
      ]
    },
    { "id": "cooldown", "duration": 600, "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Cooldown", "intervalType": "COOLDOWN" }
  ]
}

El ejemplo anterior se expande a 1 Calentamiento + 4×(umbral + Recuperación) + 1 Vuelta a la calma = 10 bloques. Los grupos de repetición pueden anidarse, pero es preferible que sean planos para mejorar la legibilidad.

Tipos de entrenamiento y variantes

El campo workoutType selecciona el paradigma; variant selecciona una sub-forma dentro de él.

workoutTypeQué esForma requerida del Intervalo
POWER (por defecto)Intervalos anclados al FTP. El rodillo mantiene los Watts objetivo en ERG, o sigue las curvas de resistencia en SIM.Cada Intervalo tiene targetPowerPercent (y opcionalmente targetPowerEndPercent para rampas).
HR_ZONEIntervalos guiados por la Frecuencia cardíaca. El rodillo ajusta los Watts en vivo para mantener la FC del ciclista en la Zona objetivo — útil cuando la carga cardiovascular es la métrica de entrenamiento (Recuperación, base, trabajo polarizado).Cada Intervalo tiene targetHrZone (1–5). El botón START muestra VINCULAR HRM hasta que el HRM está conectado.
ROUTESesiones de simulación guiadas por la pendiente. El rodillo sigue el perfil de elevación de routeProfile; el ciclista elige Cadencia y desarrollos.Los Intervalos suelen estar vacíos o contienen un único marcador de posición de longitud completa. El contenido real de la sesión vive en routeProfile.

El campo variant selecciona una sub-forma:

Packs (.ytwpack)

Cuando quieres una colección curada de entrenamientos de una sola vez, el formato .ytwpack agrupa muchos archivos .ytw junto con un manifiesto por pack. Un .ytwpack es un archivo ZIP por dentro — renómbralo a .zip y descomprímelo para ver el contenido, o impórtalo a través del instalador de packs de Your Trainer para que se instalen todos los entrenamientos con un solo toque.

Un archivo .ytwpack contiene:

El manifiesto del pack lleva información suficiente para una hoja de decisión de instalación sin necesidad de abrir cada entrenamiento. Campos de nivel superior:

CampoTipoDescripción
schema_version requeridoenteroActualmente siempre 1.
pack_id requeridostringIdentificador estable en kebab-case (p. ej. sweet-spot).
name requeridostringNombre visible que se muestra en el catálogo de packs.
description requeridostringResumen de una o dos frases visible antes de que el ciclista toque para instalar.
version requeridostring (SemVer)MAJOR.MINOR.PATCH, opcionalmente -prerelease. Patch para correcciones de contenido; minor para entrenamientos adicionales; major para cambios de esquema incompatibles. Incluido en el nombre del archivo publicado (v1.0.2.ytwpack).
content_hash requeridostringsha256: sobre la concatenación —ordenada por slug— de los bytes de cada archivo .ytw. Estable entre regeneraciones de contenido inalterado; cambia cada vez que los entrenamientos del interior cambian.
generated_at requeridostring (ISO 8601)Marca de tiempo UTC.
set requeridostringpower o hr-zone — la familia de entrenamiento a la que pertenece este pack.
category requeridostringSub-taxonomía dentro del set (p. ej. sweet-spot).
workout_count requeridoenteroNúmero de entradas .ytw en el pack.
total_ride_time_seconds requeridoenteroSuma de las duraciones de cada entrenamiento del pack.
experience_level requeridostringCalculado a partir del rango de dificultad del contenido — uno de beginner / intermediate / advanced / mixed. Formato de cable en minúsculas; la app lo capitaliza para mostrarlo.
hrm_required requeridobooleanTrue si cualquier entrenamiento del pack usa HR_ZONE.
type_mix requeridoobjectPorcentaje por categoría del tiempo total de la sesión (suma 100). Alimenta el donut de mezcla de tipos en la app, en la hoja de instalación.
duration_histogram requeridoobjectRecuento de entrenamientos por bin de duración: 0-30, 30-60, 60-90, 90+ (minutos). Alimenta el gráfico de duración en la hoja de instalación.
contents requeridoarrayEntradas completas por entrenamiento — superconjunto de la forma de entrada del manifiesto de biblioteca; cada una lleva slug, name, duration_seconds, métricas de resumen, además de un array sparkline para la representación de miniaturas.

Dos vías de instalación para un .ytwpack descargado:

Manifiesto de pack de ejemplo (con contents truncado para mayor legibilidad):

{
  "schema_version": 1,
  "pack_id": "sweet-spot",
  "name": "Sweet Spot",
  "description": "26 sweet-spot sessions across classic intervals, sustained stacks, and over-unders.",
  "version": "1.0.2",
  "content_hash": "sha256:9432a3a76015158dc71ec63…",
  "generated_at": "2025-05-28T00:00:00Z",
  "set": "power",
  "category": "sweet-spot",
  "workout_count": 26,
  "total_ride_time_seconds": 119340,
  "experience_level": "intermediate",
  "hrm_required": false,
  "type_mix":   { "sweet-spot": 100 },
  "duration_histogram": { "0-30": 0, "30-60": 5, "60-90": 12, "90+": 9 },
  "contents": [
    { "slug": "sweet-spot-3x10min-at-88pct-ftp",  "name": "Sweet Spot 3×10min @ 88% FTP",  "duration_seconds": 3300, "tss": 55.8,  "intensity_factor": 0.764, "sparkline": […] },
    { "slug": "sweet-spot-3x15min-at-90pct-ftp",  "name": "Sweet Spot 3×15min @ 90% FTP",  "duration_seconds": 4500, "tss": 81.6,  "intensity_factor": 0.808, "sparkline": […] }
    /* … 24 more workouts … */
  ]
}

Manifiestos de biblioteca y de pack

Hay dos manifiestos publicados junto a los artefactos descargables. Ambos son JSON sencillo; ambos están descritos por documentos JSON Schema que puedes consultar directamente.

URLQué listaJSON Schema
library/manifest.json Cada .ytw curado de la biblioteca — metadatos por entrenamiento para los clientes de navegación / búsqueda / filtrado. También lista las descargas .ytwpack disponibles (ruta del archivo, versión, hash de contenido, resumen de mezcla de tipos, URL del icono). /schemas/workout-manifest.json
packs/manifest.json Endpoint del catálogo de packs: cada .ytwpack publicado con sus metadatos de resumen. Misma forma de entrada por pack que el array packs del manifiesto de la biblioteca; la Pack Library en la app obtiene esto en la actualización iniciada por el ciclista. /schemas/workout-manifest.json
(dentro de cada .ytwpack) Manifiesto por pack incluido como manifest.json en la raíz del archivo — la tabla anterior documenta su forma. /schemas/workout-pack-manifest.json

Si estás creando herramientas que consumen la biblioteca — un explorador de entrenamientos personalizado, un convertidor de entrenamientos que apunta a .zwo, un panel de entrenador que expone packs — estos son los contratos contra los que validar. La misma forma de entrada por entrenamiento aparece en los arrays contents / workouts de ambos manifiestos, así que un cliente que maneja uno maneja el otro.

Ejemplos resueltos

Intervalo en rampa

Un Calentamiento de 5 minutos que sube en rampa del 40 % de FTP al 75 % de FTP mediante interpolación lineal:

{
  "id": "rampup",
  "duration": 300,
  "targetPowerPercent": 40,
  "targetPowerEndPercent": 75,
  "intensityZone": "Z1",
  "label": "Ramp up",
  "intervalType": "WARMUP"
}

Over-under

Tres series de 2 minutos al 95 % de FTP / 1 minuto al 105 % de FTP, expresadas como un grupo de repetición:

{
  "repeat": 3,
  "intervals": [
    { "id": "under", "duration": 120, "targetPowerPercent": 95,  "intensityZone": "Z4", "label": "Under" },
    { "id": "over",  "duration": 60,  "targetPowerPercent": 105, "intensityZone": "Z5", "label": "Over"  }
  ]
}

Entrenamiento por Zona de FC

Sesión de Resistencia de 30 minutos en Z2 con un pico de 3 minutos en Z4 en el medio:

{
  "programId": "hr-z2-with-surge",
  "programName": "Z2 with a Z4 surge",
  "description": "Steady Zone 2 with a single 3-minute Zone 4 surge.",
  "totalDuration": 1800,
  "workoutType": "HR_ZONE",
  "primaryLocale": "en",
  "intervals": [
    { "id": "warmup",  "duration": 300,  "targetHrZone": 1, "intensityZone": "Z1", "label": "Warmup", "intervalType": "WARMUP" },
    { "id": "endure1", "duration": 600,  "targetHrZone": 2, "intensityZone": "Z2", "label": "Endurance" },
    { "id": "surge",   "duration": 180,  "targetHrZone": 4, "intensityZone": "Z4", "label": "Surge" },
    { "id": "endure2", "duration": 420,  "targetHrZone": 2, "intensityZone": "Z2", "label": "Endurance" },
    { "id": "cooldown","duration": 300,  "targetHrZone": 1, "intensityZone": "Z1", "label": "Cooldown", "intervalType": "COOLDOWN" }
  ]
}

Multilingüe

El ejemplo mínimo de Sweet Spot con bloques strings en EN + DE + NL. Mismo entrenamiento, tres experiencias nativas:

{
  "programId": "my-sweet-spot",
  "programName": "Sweet Spot 30",
  "description": "A short sweet-spot workout.",
  "totalDuration": 1800,
  "workoutType": "POWER",
  "primaryLocale": "en",
  "intervals": [
    { "id": "warmup",   "duration": 300,  "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Warmup",     "intervalType": "WARMUP"   },
    { "id": "work",     "duration": 1200, "targetPowerPercent": 88, "intensityZone": "Z3", "label": "Sweet Spot", "intervalType": "INTERVAL",
      "cues": [
        { "offsetSec": 0,   "text": "Settle in" },
        { "offsetSec": 600, "text": "Halfway" }
      ]
    },
    { "id": "cooldown", "duration": 300,  "targetPowerPercent": 50, "intensityZone": "Z1", "label": "Cooldown",   "intervalType": "COOLDOWN" }
  ],
  "strings": {
    "en": {
      "name": "Sweet Spot 30",
      "description": "A short sweet-spot workout.",
      "labels": { "warmup": "Warmup", "work": "Sweet Spot", "cooldown": "Cooldown" },
      "cues":   { "work:0": "Settle in", "work:1": "Halfway" }
    },
    "de": {
      "name": "Sweet Spot 30",
      "description": "Ein kurzes Sweet-Spot-Training.",
      "labels": { "warmup": "Aufwärmen", "work": "Sweet Spot", "cooldown": "Ausrollen" },
      "cues":   { "work:0": "Locker einrollen", "work:1": "Halbzeit" }
    },
    "nl": {
      "name": "Sweet Spot 30",
      "description": "Een korte sweet-spot-training.",
      "labels": { "warmup": "Inrijden", "work": "Sweet Spot", "cooldown": "Uitrijden" },
      "cues":   { "work:0": "Rustig inrijden", "work:1": "Halverwege" }
    }
  }
}

Errores frecuentes

Referencia

Para búsquedas programáticas de spec de formato (tablas de campos, ejemplos, constraints, glosario), la fuente canónica legible por máquina es el Your Trainer MCP — llama get_format_spec, get_canonical_examples, get_format_constraints o get_format_glossary desde cualquier cliente MCP. Estas tools sirven desde el mismo registro de conocimiento que alimenta esta página; si la respuesta de una tool alguna vez diverge de esta página, el MCP es canónico y esta página está obsoleta.

JSON Schemas (contratos legibles por máquina para los clientes que construyan sobre estos formatos):

← Volver al Manual y Guías