Documentation

Keely for developers

Permissions.

Six scopes, named for what the person reads on the consent page. Each one matches the tables it opens, so what the database enforces is exactly what the page promises.

Updated

On this page
  1. The scopes
  2. What starts ticked
  3. The journal’s switch
  4. Not allowed is named, never empty

The scopes

ScopeOn the consent pageWhat it gives
profileWho you areYour birth year, sex, height, weight, sleep goal and max heart rate, and your band: its name, firmware and last sync
nightsMornings: Recovery and sleepEach morning’s Recovery and what moved it, HRV, resting heart rate, breathing rate, skin temperature, sleep (stages, need, regularity) and your normals
daysDays: Load and stressEach day’s Load and its target, time in heart-rate zones, steps, stress (day, night and moments) and naps
workoutsWorkoutsWorkouts and activities: the sport, times, Load, heart rate and zones
journalRead your journalYour journal and its tags, only while you share your journal in the Keely app (Journal › Assistants)
journal:writeAdd to your journalAdd entries and tags when you ask it to, and delete what it added

What starts ticked

On the consent page, nights, days and workouts start ticked; profile, journal and journal:write start unticked, and journal:write can’t be ticked without journal. Ask only for what your app uses: the fewer the scopes, the more people allow.

The page shows only the scopes your app registered, and the person may untick any of them. So never assume you got what you asked for: read scopes from GET /v1/me after connecting, and handle 403 insufficient_scope on every call, because the person can narrow a permission later and the change holds at your next request.

GET /v1/changes needs at least one scope, and lists only the kinds your scopes cover: nights with nights, days with days, workouts with workouts, the journal’s rows with journal. An app whose every permission the person turned off reads nothing, there as everywhere.

The journal’s switch

The journal has a second gate, the person’s own. It reaches their account only while Let assistants read and add to your journal is on in the Keely app. Until then, every journal endpoint answers 409 journal_off, whatever the scopes say.

Not allowed is named, never empty

When parts of an answer need scopes you don’t have, those keys are left out and listed in not_allowed: a day read with nights alone comes with "not_allowed": ["days", "workouts"]. When the whole answer needs a scope you lack, the API answers 403 insufficient_scope, with scope, the one needed, and scopes, the ones granted, so an empty table never reads as “nothing happened”.

403 insufficient_scope
{
  "error": "insufficient_scope",
  "message": "This person hasn’t allowed your app to read their workouts.",
  "scope": "workouts",
  "scopes": ["nights", "days"]
}