Authentifizierung
OAuth-Apps
Für Apps, die im Namen anderer Gravl-Nutzer handeln. Standard-OAuth-2.0-Authorization-Code mit PKCE: Nutzer gewähren deiner App bestimmte Scopes, du bekommst kurzlebige Access Tokens mit einem rotierenden Refresh Token, und der Grant ist jederzeit widerrufbar.
1. App registrieren
Du registrierst deine App selbst. Melde dich mit deinem Gravl-Account auf app.gravl.ai/settings/developer an und öffne den Bereich OAuth-Apps neben deinen persönlichen Access Tokens.
OAuth-App erstellenDort gibst du an:
- Den Namen deiner App und eine kurze Beschreibung, was sie tut. Der Name darf „Gravl“ nicht enthalten
- Optional ein Logo: ein quadratisches PNG, JPEG oder WebP (kein SVG), mindestens 128×128 px und höchstens 1 MB. Es erscheint auf dem Consent-Screen neben dem Namen deiner App
- Die Homepage deiner App: eine
https-URL - Bis zu 5 Redirect URIs: absolute
https-URLs (http://localhostist für die Entwicklung erlaubt) - Die Scopes, die deine App braucht. Fordere das Minimum an; Nutzer sehen genau, was du anfragst
- Den Client-Typ: Confidential für serverseitige Apps, die ein
client_secretsicher aufbewahren können, oder Public für Browser- und native Apps, die kein Secret bekommen und PKCE verwenden müssen
Du erhältst sofort eine client_id (gci_…). Confidential Clients bekommen zusätzlich ein client_secret (gcs_…, wird nur einmal angezeigt; behandle es wie ein Passwort). Das Secret kannst du später auf derselben Seite rotieren. Pro Account sind bis zu 5 OAuth-Apps möglich.
Entwicklungsmodus und Prüfung
Eine neue App startet im Entwicklungsmodus. Sie funktioniert sofort, aber nur dein eigener Gravl-Account kann sie autorisieren. Andere Nutzer sehen auf dem Consent-Screen einen Hinweis und können sich nicht verbinden. So kannst du den ganzen Flow bauen und testen.
- Wenn deine App bereit ist, klick auf Zur Prüfung einreichen. Wir prüfen Name, Beschreibung, Logo, Homepage, Redirect URIs und Scopes und schicken dir die Entscheidung per E-Mail
- Nach der Freigabe kann jeder Gravl-Nutzer deine App verbinden
- Lehnen wir die App ab, findest du den Grund in der E-Mail und auf der Einstellungsseite. Bearbeite die App und reiche sie erneut ein
- Freigegebene Apps lassen sich auf der Einstellungsseite nicht mehr bearbeiten, auch das Logo nicht
Für Änderungen an einer freigegebenen App oder Fragen zu Registrierung und Prüfung schreib an developers@gravl.ai.
2. Nutzer zum Consent-Screen schicken
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=S256Der Nutzer meldet sich mit seinem Gravl-Account an, sieht den Namen deiner App und die angefragten Scopes in verständlicher Sprache und stimmt zu. Sein Browser kommt zu deiner redirect_uri zurück, mit ?code=gac_…&state=… (oder error=access_denied, wenn er abbricht).
- Codes haben das Präfix
gac_, sind 10 Minuten gültig, einmalig verwendbar und an deine App sowie dieredirect_urigebunden, für die sie ausgestellt wurden - PKCE (S256) ist für Public Clients erforderlich (Browser- oder native Apps, die kein
client_secrethaben) und für alle anderen dringend empfohlen - Prüfe immer, ob
statemit dem übereinstimmt, was du gesendet hast; das ist dein CSRF-Schutz
Public Clients lassen client_secret am Token-Endpoint weg; PKCE ist ihre Client-Authentifizierung. Den Client-Typ wählst du, wenn du die App erstellst.
3. Code einlösen
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 | Lebensdauer | Hinweise |
|---|---|---|
access_token | 6 Stunden | Bearer Token für /api/v1-Requests. |
refresh_token | Bis zu 180 Tage | Einmalig verwendbar; jeder Refresh widerruft es und stellt ein neues Paar aus (Rotation). |
4. Refresh
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_…Die Response hat dieselbe Form wie beim Code-Austausch. Das vorgelegte Refresh Token wird in derselben Transaktion widerrufen; speichere also immer erst das neue refresh_token, bevor du das alte verwirfst. Das erneute Einreichen eines bereits benutzten Refresh Tokens gibt invalid_grant zurück.
5. Widerrufen
curl -X POST https://api.gravl.ai/oauth/revoke \
-d token=grt_… \
-d client_id=gci_… \
-d client_secret=gcs_…- Der Widerruf eines Access Tokens beendet nur dieses Token
- Der Widerruf eines Refresh Tokens widerruft den gesamten Grant: jedes ausstehende Token für dieses Nutzer-App-Paar
- Gemäß RFC 7009 gibt der Endpoint auch bei unbekannten Tokens
200zurück; nur falsche Client-Credentials erzeugen einen Fehler - Nutzer können den Zugriff deiner App auch aus ihrem Account heraus widerrufen
Fehler am Token-Endpoint
Fehler folgen RFC 6749: { "error": "…", "error_description": "…" }:
| Fehler | Status | Bedeutung |
|---|---|---|
invalid_request | 400 | Ein erforderlicher Parameter fehlt (z. B. code, refresh_token). |
invalid_client | 401 | Unbekannte client_id, falsches client_secret, oder die App ist gesperrt. |
invalid_grant | 400 | Code/Refresh Token ist abgelaufen, widerrufen, bereits benutzt, gehört zu einer anderen App, oder die PKCE-/redirect_uri-Prüfung schlug fehl. |
unsupported_grant_type | 400 | grant_type muss authorization_code oder refresh_token sein. |