Autenticación
Apps OAuth
Para apps que actúan en nombre de otros usuarios de Gravl. OAuth 2.0 authorization-code estándar con PKCE: los usuarios conceden a tu app scopes concretos, tú obtienes tokens de acceso de corta duración con un token de refresco rotatorio, y el grant es revocable en cualquier momento.
1. Registra tu app
El registro es manual mientras la API está en beta. Escribe a developers@gravl.ai con:
- El nombre de tu app y una breve descripción de lo que hace
- Tu(s) redirect URI(s) de OAuth: URLs
httpsabsolutas (http://localhostpermitido para desarrollo) - Los scopes que necesita tu app; pide el mínimo, los usuarios ven exactamente lo que solicitas
Recibirás un client_id (gci_…) y un client_secret (gcs_…, se muestra una sola vez; guárdalo como una contraseña).
2. Envía al usuario a la pantalla de consentimiento
https://api.gravl.ai/oauth/authorize
?client_id=gci_…
&redirect_uri=https://yourapp.example/callback // must be registered exactly
&scope=workouts:read stats:read // omit for all allowed scopes
&state=<random value you verify on return>
&code_challenge=<S256(code_verifier)>
&code_challenge_method=S256El usuario inicia sesión con su cuenta de Gravl, ve el nombre de tu app y los scopes solicitados en lenguaje claro, y aprueba; su navegador vuelve a tu redirect_uri con ?code=gac_…&state=… (o error=access_denied si cancela).
- Los códigos llevan el prefijo
gac_, son válidos 10 minutos, de un solo uso, y están ligados a tu app y a laredirect_uripara la que se emitieron - PKCE (S256) es obligatorio para clientes públicos (apps de navegador o nativas, que no tienen
client_secret) y muy recomendable para todos - Verifica siempre que
statecoincide con lo que enviaste: es tu protección CSRF
Los clientes públicos omiten client_secret en el endpoint de token; PKCE es su autenticación de cliente. Dinos de qué tipo es tu app al registrarla.
3. Intercambia el código
curl -X POST https://api.gravl.ai/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=authorization_code \
-d code=gac_… \
-d client_id=gci_… \
-d client_secret=gcs_… \
-d code_verifier=<your PKCE verifier> \
-d redirect_uri=https://yourapp.example/callback
{
"access_token": "gat_…",
"token_type": "Bearer",
"expires_in": 21600,
"refresh_token": "grt_…",
"scope": "workouts:read stats:read"
}| Token | Vida útil | Notas |
|---|---|---|
access_token | 6 horas | Token bearer para las peticiones a /api/v1. |
refresh_token | Hasta 180 días | De un solo uso: cada refresco lo revoca y emite un par nuevo (rotación). |
4. Refresca
curl -X POST https://api.gravl.ai/oauth/token \
-d grant_type=refresh_token \
-d refresh_token=grt_… \
-d client_id=gci_… \
-d client_secret=gcs_…La respuesta tiene la misma forma que el intercambio del código. El token de refresco presentado se revoca en la misma transacción: persiste siempre el nuevo refresh_token antes de descartar el antiguo. Reutilizar un token de refresco ya usado devuelve invalid_grant.
5. Revoca
curl -X POST https://api.gravl.ai/oauth/revoke \
-d token=grt_… \
-d client_id=gci_… \
-d client_secret=gcs_…- Revocar un token de acceso mata solo ese token
- Revocar un token de refresco revoca el grant completo: todos los tokens vigentes para ese par usuario + app
- Según la RFC 7009 el endpoint devuelve
200incluso para tokens desconocidos; solo unas credenciales de cliente incorrectas producen un error - Los usuarios también pueden revocar el acceso de tu app desde su cuenta
Errores del endpoint de token
Los errores siguen la RFC 6749: { "error": "…", "error_description": "…" }:
| Error | Estado | Significado |
|---|---|---|
invalid_request | 400 | Falta un parámetro obligatorio (p. ej. code, refresh_token). |
invalid_client | 401 | client_id desconocido, client_secret incorrecto o la app está suspendida. |
invalid_grant | 400 | El código o el token de refresco expiró, fue revocado, ya se usó, pertenece a otra app, o falló la validación de PKCE/redirect_uri. |
unsupported_grant_type | 400 | grant_type debe ser authorization_code o refresh_token. |