Authentication
Personal access tokens
The fastest way in. A personal token is bound to your own account and can never see anyone else’s data — perfect for dashboards, scripts, spreadsheets and side projects.
Create a token
The easiest way is the dashboard: open app.gravl.ai/settings/developer and create the token there — name it, pick scopes and an expiry, and copy the value when it’s shown. The endpoints below do the same thing programmatically.
Personal tokens are managed from your own account, so these three endpoints use your normal Gravl session (the same authentication the mobile app uses) — not the token itself.
POST https://api.gravl.ai/api/user/personal-tokens
Authorization: Bearer <your Gravl session token>
Content-Type: application/json
{
"name": "My stats dashboard",
"scopes": ["workouts:read", "stats:read"],
"expiresInDays": 365
}
{
"token": "gat_k3rB…", // ← shown exactly once, store it now
"clientId": "gci_9fJq…",
"name": "My stats dashboard",
"scopes": "workouts:read stats:read",
"expiresAt": "2027-07-14T09:30:00Z"
}| Field | Type | Notes |
|---|---|---|
name | string | Required. What you’re building — shown when you list your tokens. Max 120 chars. |
scopes | string[] | Optional. Defaults to all scopes (it’s your own data). See scopes. |
expiresInDays | number | Optional. 1–365; defaults to 365. |
The token value is returned once and stored only as a hash. Lose it and you revoke + recreate — there is no way to read it back.
Use it
Send the token as a bearer token against any /api/v1 endpoint it has scopes for:
curl "https://api.gravl.ai/api/v1/stats" \
-H "Authorization: Bearer gat_k3rB…"
{
"streak": { "current": 6, "longest": 14, "workoutsThisWeek": 3 },
"totalXp": 12480,
"trophyCount": 22
}List and revoke
| Method | Path | Description |
|---|---|---|
| GET | /api/user/personal-tokens | Your active tokens — name, clientId, scopes, created, last used, expiry. Never the token value. |
| DELETE | /api/user/personal-tokens/{clientId} | Revokes the token immediately. In-flight requests with it start failing with 401 right away. |
Limits
| Limit | Value |
|---|---|
| Active tokens per account | 10 |
| Maximum lifetime | 365 days |
| Rate limit | 100 requests / 15 minutes (per token per user) |
Need longer-lived automation, app-to-app access, or higher limits? That’s what OAuth apps are for.