Referencia

Convenciones y errores

Las reglas que se cumplen en todos los endpoints, para que solo tengas que aprenderlas una vez.

Paginación

Los endpoints de listado aceptan page (empezando en 1) y pageSize (de 1 a 100, por defecto 30) como parámetros de query y envuelven los resultados en un envoltorio:

{
  "items": [ … ],
  "pageNumber": 2,
  "totalPages": 9,
  "totalCount": 174,
  "hasPreviousPage": true,
  "hasNextPage": true
}

Los enums son cadenas en camelCase

Los valores enum son siempre cadenas en camelCase, nunca enteros: "pounds", "kilometers", "oneRepMax", "chest", "normal". Trata los valores enum desconocidos como compatibles hacia delante: pueden aparecer nuevos sin cambio de versión.

Unidades

MedidaUnidad
Peso (series, récords)Libras
DistanciaMetros
Duración de serie / récordSegundos
Duración del entrenamientoMinutos (durationMinutes)
Medidas corporalesEl sistema de unidades del weightUnit de la entrada (pulgadas con libras, centímetros con kilogramos)

Las unidades de visualización preferidas del usuario están en /api/v1/user: convierte en el borde de tu app, no en el almacenamiento.

Identificadores

  • Datos de usuario (entrenamientos, plantillas, splits, medidas): GUIDs estables
  • Datos de catálogo (ejercicios, equipamiento): ids enteros estables compartidos con la app de Gravl
  • El usuario: un id de cadena opaco, estable en todos los endpoints y tokens

Fechas

Todas las marcas de tiempo son UTC, ISO 8601 (2026-07-12T17:03:00Z). Los filtros por rango de fechas (startDate, endDate) son inclusivos.

Rate limits

SuperficieLímiteClave
/api/v1/*100 peticiones / 15 minapp + usuario
/oauth/*10 peticiones / mindirección IP

Superar un límite devuelve 429 con una cabecera Retry-After cuando está disponible. Aplica backoff exponencial y no hagas polling: la mayoría de los datos personales cambian a velocidad humana.

Errores

EstadoCuándoCuerpo
401Token ausente, malformado, expirado o revocado; app suspendidaVacío (desafío WWW-Authenticate)
403Token válido, falta el scopeProblem details con el nombre del scope que falta
404El recurso no existe, o pertenece a otro usuarioProblem details
429Rate limit superadoVacío; cabecera Retry-After
400Fallo de validación (tamaño de página incorrecto, parámetros malformados)Problem details con errores por campo
Problem details (RFC 7807)
{
  "status": 403,
  "title": "Missing scope",
  "detail": "This authorization is missing the 'measurements:read' scope."
}

Fíjate en la regla del 404 para datos ajenos: pedir por id el entrenamiento de otro usuario devuelve 404, no 403. La API nunca confirma que existan datos que no puedes ver.