Authentification

Apps OAuth

Pour les apps qui agissent au nom d’autres utilisateurs Gravl. OAuth 2.0 authorization-code standard avec PKCE : les utilisateurs accordent à ton app des scopes précis, tu obtiens des access tokens de courte durée avec un refresh token rotatif, et l’autorisation est révocable à tout moment.

1. Enregistre ton app

L’enregistrement est manuel tant que l’API est en bêta. Écris à developers@gravl.ai avec :

  • Le nom de ton app et une courte description de ce qu’elle fait
  • Ta ou tes redirect URI OAuth : des URLs https absolues (http://localhost autorisé pour le développement)
  • Les scopes dont ton app a besoin : demande le minimum ; les utilisateurs voient exactement ce que tu demandes

Tu recevras un client_id (gci_…) et un client_secret (gcs_…, affiché une seule fois : stocke-le comme un mot de passe).

2. Envoie l’utilisateur vers l’écran de consentement

GET /oauth/authorize
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=S256

L’utilisateur se connecte avec son compte Gravl, voit le nom de ton app et les scopes demandés en langage clair, puis approuve : son navigateur revient sur ta redirect_uri avec ?code=gac_…&state=… (ou error=access_denied s’il annule).

  • Les codes sont préfixés gac_, valables 10 minutes, à usage unique, et liés à ton app et à la redirect_uri pour laquelle ils ont été émis
  • PKCE (S256) est requis pour les clients publics (apps navigateur ou natives, qui n’ont pas de client_secret) et fortement recommandé pour tout le monde
  • Vérifie toujours que state correspond à ce que tu as envoyé : c’est ta protection CSRF

Les clients publics omettent client_secret sur l’endpoint de token : PKCE fait office d’authentification client. Dis-nous de quel type est ton app au moment de l’enregistrement.

3. Échange le code

POST /oauth/token — authorization_code
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"
}
TokenDurée de vieNotes
access_token6 heuresToken Bearer pour les requêtes /api/v1.
refresh_tokenJusqu’à 180 joursUsage unique : chaque refresh le révoque et émet une nouvelle paire (rotation).

4. Rafraîchir

POST /oauth/token — refresh_token
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 réponse a la même forme que l’échange de code. Le refresh token présenté est révoqué dans la même transaction : persiste toujours le nouveau refresh_token avant de jeter l’ancien. Rejouer un refresh token déjà utilisé renvoie invalid_grant.

5. Révoquer

POST /oauth/revoke
curl -X POST https://api.gravl.ai/oauth/revoke \
  -d token=grt_… \
  -d client_id=gci_… \
  -d client_secret=gcs_…
  • Révoquer un access token ne tue que ce token
  • Révoquer un refresh token révoque l’autorisation entière : tous les tokens en circulation pour ce couple utilisateur + app
  • Conformément à la RFC 7009, l’endpoint renvoie 200 même pour un token inconnu : seuls de mauvais identifiants client produisent une erreur
  • Les utilisateurs peuvent aussi révoquer l’accès de ton app depuis leur compte

Erreurs de l’endpoint de token

Les erreurs suivent la RFC 6749, au format { "error": "…", "error_description": "…" }:

ErreurStatutSignification
invalid_request400Un paramètre requis est manquant (p. ex. code, refresh_token).
invalid_client401client_id inconnu, mauvais client_secret, ou app suspendue.
invalid_grant400Le code ou refresh token est expiré, révoqué, déjà utilisé, appartient à une autre app, ou la validation PKCE/redirect_uri a échoué.
unsupported_grant_type400grant_type doit être authorization_code ou refresh_token.