{"openapi":"3.1.0","info":{"title":"Top Nutritionist API","version":"1.2026-10-04.1","summary":"Record meals, activity, sleep and wellbeing notes from any assistant; read days and reports; manage report links.","description":"Top Nutritionist is a recording, organisation and sharing tool for nutritionists, trainers and their clients. Through this API the person's own assistant (any model) estimates food quantities and nutrients and sends the records; the server stores them, computes totals and builds reports. The server never generates dietary, exercise or medical advice. Connect with POST /connect (e-mail approval) or OAuth 2.1 (metadata at /.well-known/oauth-authorization-server). Instructions for assistants: https://nutri.coghorizon.com/connect.md. Human documentation: https://nutri.coghorizon.com/developers.","termsOfService":"https://nutri.coghorizon.com/terms","contact":{"name":"Top Nutritionist","url":"https://nutri.coghorizon.com/contact"}},"servers":[{"url":"https://nutri.coghorizon.com/api/v1"}],"externalDocs":{"description":"Instructions for assistants","url":"https://nutri.coghorizon.com/connect.md"},"tags":[{"name":"connect","description":"Connecting an assistant to a person's diary"},{"name":"account"},{"name":"profiles"},{"name":"records","description":"Meals, activity, sleep, wellbeing notes"},{"name":"reports"},{"name":"share","description":"Report links for a nutritionist or trainer"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Token from POST /connect (e-mail approval). Send as Authorization: Bearer <token>."},"oauth":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://nutri.coghorizon.com/oauth/authorize","tokenUrl":"https://nutri.coghorizon.com/oauth/token","refreshUrl":"https://nutri.coghorizon.com/oauth/token","scopes":{"records:read":"Read meals, activity, sleep and wellbeing notes","records:write":"Add and delete meals, activity, sleep and wellbeing notes","reports:read":"Read daily, weekly and monthly reports","share:manage":"Create and revoke report links"}}}}},"schemas":{"Problem":{"type":"object","description":"RFC 9457 problem details","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string"},"issues":{"type":"array","items":{"type":"object"}}},"required":["status","detail","code"]},"ConnectInput":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"The person's e-mail address: their identity in Top Nutritionist. We send the approval link there."},"client_name":{"type":"string","minLength":1,"maxLength":80,"description":"Name of the assistant or application asking for access, shown to the person"},"scopes":{"description":"Access requested; all four when absent","minItems":1,"type":"array","items":{"type":"string","enum":["records:read","records:write","reports:read","share:manage"]}},"language":{"description":"Language of the e-mail and the approval page","type":"string","enum":["en","es","ru"]}},"required":["email","client_name"]},"LogMealInput":{"type":"object","properties":{"profile_id":{"description":"Profile to record in; the default profile when absent","type":"string","maxLength":64},"meal_type":{"type":"string","enum":["breakfast","lunch","dinner","snack","other"],"description":"Breakfast, lunch, dinner, snack or other"},"eaten_at":{"description":"When the meal was eaten, ISO 8601 with offset; now when absent","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"description":{"description":"What the person said or typed about the meal, kept in full","type":"string","maxLength":2000},"items":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Food as the person named it, in their language"},"description":{"description":"Preparation or brand, if said","type":"string","maxLength":500},"portion":{"description":"Portion in everyday terms: 2 slices, a bowl, 150 g","type":"string","maxLength":120},"weight_g":{"description":"Estimated weight in grams","type":"number","exclusiveMinimum":0,"maximum":20000},"kcal":{"type":"number","minimum":0,"maximum":20000,"description":"Estimated energy, kcal"},"protein_g":{"type":"number","minimum":0,"maximum":2000,"description":"Protein, g"},"carbs_g":{"type":"number","minimum":0,"maximum":2000,"description":"Carbohydrates, g"},"fat_g":{"type":"number","minimum":0,"maximum":2000,"description":"Fat, g"},"fiber_g":{"description":"Fibre, g","type":"number","minimum":0,"maximum":500},"sugar_g":{"description":"Sugar, g","type":"number","minimum":0,"maximum":2000},"sodium_mg":{"description":"Sodium, mg","type":"number","minimum":0,"maximum":100000},"confidence":{"description":"How sure the estimate is, 0 to 1","type":"number","minimum":0,"maximum":1}},"required":["name","kcal","protein_g","carbs_g","fat_g"]},"description":"Each food with the assistant's estimate"},"model":{"description":"Model that produced the estimates, for provenance in the report","type":"string","maxLength":120},"confidence":{"description":"Overall confidence, 0 to 1","type":"number","minimum":0,"maximum":1},"notes":{"description":"The person's own note or correction","type":"string","maxLength":1000}},"required":["meal_type","items"]},"ActivityInput":{"type":"object","properties":{"steps":{"type":"integer","minimum":0,"maximum":200000},"active_kcal":{"description":"Active energy, kcal (not total)","type":"number","minimum":0,"maximum":20000},"total_kcal":{"description":"Total energy for the day, kcal, if the tracker shows it","type":"number","minimum":0,"maximum":20000},"distance_km":{"type":"number","minimum":0,"maximum":1000},"exercise_minutes":{"type":"integer","minimum":0,"maximum":1440},"resting_hr":{"description":"Resting heart rate, bpm","type":"integer","minimum":20,"maximum":250},"workouts":{"maxItems":30,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","minLength":1,"maxLength":80,"description":"Walk, run, strength, yoga..."},"minutes":{"type":"integer","minimum":0,"maximum":1440},"kcal":{"type":"number","minimum":0,"maximum":20000}},"required":["type"]}},"source_app":{"description":"Tracker or app the numbers come from; the connected assistant when absent","type":"string","maxLength":80},"confidence":{"type":"number","minimum":0,"maximum":1}}},"SleepInput":{"type":"object","properties":{"bedtime":{"description":"HH:MM, 24 h","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"wake_time":{"description":"HH:MM, 24 h","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"in_bed_minutes":{"type":"integer","minimum":0,"maximum":1440},"asleep_minutes":{"type":"integer","minimum":0,"maximum":1440},"deep_minutes":{"type":"integer","minimum":0,"maximum":1440},"rem_minutes":{"type":"integer","minimum":0,"maximum":1440},"light_minutes":{"type":"integer","minimum":0,"maximum":1440},"awake_minutes":{"type":"integer","minimum":0,"maximum":1440},"score":{"description":"Sleep score as the tracker shows it","type":"integer","minimum":0,"maximum":100},"efficiency_pct":{"type":"number","minimum":0,"maximum":100},"avg_hr":{"type":"integer","minimum":20,"maximum":250},"hrv_ms":{"type":"number","minimum":0,"maximum":500},"source_app":{"type":"string","maxLength":80},"confidence":{"type":"number","minimum":0,"maximum":1}}},"WellbeingInput":{"type":"object","properties":{"profile_id":{"type":"string","maxLength":64},"text":{"type":"string","minLength":1,"maxLength":5000,"description":"What the person said about how they feel, kept in full"},"recorded_at":{"description":"When it was said; now when absent","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"statements":{"description":"The statements listed from the text, as the person made them; none when the assistant did not list them","maxItems":60,"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["activity","food","sleep","feeling","body","other"]},"text":{"type":"string","minLength":1,"maxLength":500,"description":"One statement in the person's words"},"when":{"description":"Time reference as said","anyOf":[{"type":"string","maxLength":80},{"type":"null"}]}},"required":["kind","text"]}},"links":{"description":"Connections the person drew themselves","maxItems":30,"type":"array","items":{"type":"object","properties":{"did":{"type":"string","minLength":1,"maxLength":300,"description":"What the person did, ate or how they slept, as said"},"felt":{"type":"string","minLength":1,"maxLength":300,"description":"How they said they felt in connection with it"},"quote":{"type":"string","minLength":1,"maxLength":500,"description":"The words of the note that connect the two"}},"required":["did","felt","quote"]}},"language":{"description":"Language of the text, BCP 47","type":"string","maxLength":8},"model":{"type":"string","maxLength":120}},"required":["text"]},"ShareLinkInput":{"type":"object","properties":{"profile_id":{"description":"One profile; every profile of the account when absent","type":"string","maxLength":64},"expires_in_days":{"description":"Link lifetime; no expiry when absent","type":"integer","minimum":1,"maximum":365}}},"ProfileInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60}},"required":["name"]}}},"paths":{"/meta":{"get":{"tags":["connect"],"operationId":"getMeta","summary":"Versions, URLs and scopes; compare instructions_version to know when to re-read /connect.md","responses":{"200":{"description":"Metadata","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/connect":{"post":{"tags":["connect"],"operationId":"connect","summary":"Ask the person for access: we e-mail them an approval link; poll until approved","description":"The person's e-mail address is their identity in Top Nutritionist (the same address links the Telegram bot to the website). Ask the person for it, explain that an approval e-mail will arrive, then poll the returned poll_url with the poll_token every 5 seconds. The token is delivered exactly once. Limits: 3 requests per e-mail per hour.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectInput"}}}},"responses":{"202":{"description":"Request created; the e-mail is on its way","content":{"application/json":{"schema":{"type":"object"},"example":{"request_id":"…","poll_token":"…","status":"pending","expires_in":1800,"poll_interval":5,"poll_url":"https://nutri.coghorizon.com/api/v1/connect/…"}}}},"400":{"description":"Invalid input","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests for this e-mail or network","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"The e-mail could not be sent","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/connect/{id}":{"get":{"tags":["connect"],"operationId":"pollConnect","summary":"Poll a connection request; status approved carries the bearer token once","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]}],"description":"Send the poll_token as Authorization: Bearer <poll_token> (or ?poll_token=). Statuses: pending, approved (with token), consumed, denied, expired.","responses":{"200":{"description":"Status","content":{"application/json":{"schema":{"type":"object"},"example":{"status":"approved","token":"tn_k_…","token_type":"Bearer","scopes":["records:read","records:write","reports:read","share:manage"],"account":{"id":"…","email":"person@example.org","language":"en"}}}}},"404":{"description":"Unknown request or wrong poll token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Polling too fast","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me":{"get":{"tags":["account"],"operationId":"getMe","summary":"The connected account, the token's scopes and the profiles","security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tokens":{"get":{"tags":["account"],"operationId":"listTokens","summary":"Tokens of the account (never the secrets)","security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tokens/current":{"delete":{"tags":["account"],"operationId":"revokeCurrentToken","summary":"Disconnect: revoke the token used for this call","security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/profiles":{"get":{"tags":["profiles"],"operationId":"listProfiles","summary":"Profiles of the account (a person can keep several diaries)","security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Profiles","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["profiles"],"operationId":"createProfile","summary":"Create a profile","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileInput"}}}},"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/meals":{"post":{"tags":["records"],"operationId":"logMeal","summary":"Record a meal with the assistant's estimates per food","description":"The assistant estimates each food (weight, kcal, protein, carbohydrates, fat; fibre, sugar, sodium when known) from what the person said or showed, states its confidence, and sends the result. Keep the person's words in description; name the model in model. The server stores, totals and reports; it never judges the meal.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogMealInput"}}}},"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"201":{"description":"The stored meal with its items and totals","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["records"],"operationId":"listMeals","summary":"Meals of a day","parameters":[{"name":"day","in":"query","schema":{"type":"string"},"description":"YYYY-MM-DD, today when absent"},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Meals","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/meals/{id}":{"delete":{"tags":["records"],"operationId":"deleteMeal","summary":"Delete a meal","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/days/{day}":{"get":{"tags":["records"],"operationId":"getDay","summary":"Everything recorded on a day: meals with totals, activity, sleep, wellbeing notes, the profile's targets","parameters":[{"name":"day","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"Calendar day YYYY-MM-DD"},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Day","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/days":{"get":{"tags":["records"],"operationId":"listDays","summary":"Per-day totals, activity and sleep over a range (up to 93 days)","parameters":[{"name":"from","in":"query","schema":{"type":"string"}},{"name":"to","in":"query","schema":{"type":"string"}},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"security":[{"bearer":[]},{"oauth":["records:read"]}],"responses":{"200":{"description":"Days","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/days/{day}/activity":{"put":{"tags":["records"],"operationId":"putActivity","summary":"Set the day's activity (steps, energy, workouts); replaces earlier values for that day","parameters":[{"name":"day","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"Calendar day YYYY-MM-DD"},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityInput"}}}},"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Activity","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/days/{day}/sleep":{"put":{"tags":["records"],"operationId":"putSleep","summary":"Set the night's sleep (day = wake-up date); replaces earlier values","parameters":[{"name":"day","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"Calendar day YYYY-MM-DD"},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SleepInput"}}}},"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Sleep","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/activity/{id}":{"delete":{"tags":["records"],"operationId":"deleteActivity","summary":"Delete an activity day","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sleep/{id}":{"delete":{"tags":["records"],"operationId":"deleteSleep","summary":"Delete a sleep night","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/wellbeing":{"post":{"tags":["records"],"operationId":"addWellbeingNote","summary":"Record how the person says they feel, in their words; optionally the statements listed from it","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WellbeingInput"}}}},"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"201":{"description":"Note","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/wellbeing/{id}":{"delete":{"tags":["records"],"operationId":"deleteWellbeingNote","summary":"Delete a wellbeing note","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]},{"oauth":["records:write"]}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/reports/{period}":{"get":{"tags":["reports"],"operationId":"getReport","summary":"Totals, averages, top foods, meal breakdown, activity and sleep averages for today, this week or this month","parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string","enum":["daily","weekly","monthly"]}},{"name":"profile_id","in":"query","required":false,"schema":{"type":"string"},"description":"Profile to use; the default profile when absent"}],"security":[{"bearer":[]},{"oauth":["reports:read"]}],"responses":{"200":{"description":"Report","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/share-links":{"get":{"tags":["share"],"operationId":"listShareLinks","summary":"Active report links","security":[{"bearer":[]},{"oauth":["share:manage"]}],"responses":{"200":{"description":"Links","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["share"],"operationId":"createShareLink","summary":"Create a report link the person can give their nutritionist or trainer","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkInput"}}}},"security":[{"bearer":[]},{"oauth":["share:manage"]}],"responses":{"201":{"description":"Link","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/share-links/{id}":{"delete":{"tags":["share"],"operationId":"revokeShareLink","summary":"Revoke a report link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearer":[]},{"oauth":["share:manage"]}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Token lacks the scope","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}}}