{"openapi":"3.1.0","info":{"title":"REPSLog API","version":"1.0.0","description":"Log and read REPS work hours. Authenticate with an API key (`Authorization: Bearer rl_…`) or a WorkOS OAuth bearer token. Requires a REPSLog Premium subscription."},"servers":[{"url":"https://api.reps-log.com/v1"}],"security":[{"apiKey":[]},{"oauth2":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"API key: rl_<keyId>.<secret>"},"oauth2":{"type":"http","scheme":"bearer","description":"WorkOS OAuth access token"}}},"paths":{"/time-logs":{"post":{"operationId":"createTimeLog","summary":"Create a time log","description":"Logs work time against an existing property. Idempotent via the `Idempotency-Key` header.","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","description","durationMinutes"],"properties":{"propertyId":{"type":"string"},"description":{"type":"string","maxLength":2000},"durationMinutes":{"type":"integer","minimum":1,"maximum":1440},"categoryId":{"type":"string"},"performedOn":{"type":"string","format":"date"},"performedBy":{"type":"string","enum":["self","spouse"]}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"propertyId":{"type":"string"},"categoryId":{"type":"string"},"description":{"type":"string"},"durationMinutes":{"type":"number"},"performedOn":{"type":"string"},"performedBy":{"type":"string"},"isSTR":{"type":"boolean"},"source":{"type":"string"}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}},"get":{"operationId":"listTimeLogs","summary":"List time logs","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}},{"name":"propertyId","in":"query","schema":{"type":"string"}},{"name":"categoryId","in":"query","schema":{"type":"string"}},{"name":"propertyType","in":"query","schema":{"type":"string","enum":["str","ltr"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"propertyId":{"type":"string"},"categoryId":{"type":"string"},"description":{"type":"string"},"durationMinutes":{"type":"number"},"performedOn":{"type":"string"},"performedBy":{"type":"string"},"isSTR":{"type":"boolean"},"source":{"type":"string"}}}},"nextCursor":{"type":"string"}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/time-logs/{id}":{"patch":{"operationId":"updateTimeLog","summary":"Update a time log","description":"Edit fields of an existing entry; pass only the fields to change. STR/LTR is re-derived from the property.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"propertyId":{"type":"string"},"description":{"type":"string","maxLength":2000},"durationMinutes":{"type":"integer","minimum":1,"maximum":1440},"categoryId":{"type":"string"},"performedOn":{"type":"string","format":"date"},"performedBy":{"type":"string","enum":["self","spouse"]}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"propertyId":{"type":"string"},"categoryId":{"type":"string"},"description":{"type":"string"},"durationMinutes":{"type":"number"},"performedOn":{"type":"string"},"performedBy":{"type":"string"},"isSTR":{"type":"boolean"},"source":{"type":"string"}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}},"delete":{"operationId":"deleteTimeLog","summary":"Delete a time log","description":"Removes the entry from the user's logs. There is no in-app undo.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string"},"success":{"type":"boolean","enum":[true]}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/properties":{"get":{"operationId":"listProperties","summary":"List properties","description":"Returns all of the user's properties (no pagination).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"nickname":{"type":"string"},"formattedAddress":{"type":"string"},"isSTR":{"type":"boolean"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/categories":{"get":{"operationId":"listCategories","summary":"List categories","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/participants":{"get":{"operationId":"listParticipants","summary":"List participants","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/hours-summary":{"get":{"operationId":"getHoursSummary","summary":"Aggregate logged hours for a year","description":"Year-scoped totals from precomputed stats. Filter by at most one of propertyId / categoryId / participantId; propertyType narrows to STR or LTR. For arbitrary date ranges, use /time-logs.","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"propertyId","in":"query","schema":{"type":"string"}},{"name":"categoryId","in":"query","schema":{"type":"string"}},{"name":"participantId","in":"query","schema":{"type":"string"}},{"name":"propertyType","in":"query","schema":{"type":"string","enum":["str","ltr"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"year":{"type":"number"},"totalHours":{"type":"number"},"ltrHours":{"type":"number"},"strHours":{"type":"number"},"entryCount":{"type":"number"},"byProperty":{"type":"array","items":{"type":"object","properties":{"propertyId":{"type":"string"},"nickname":{"type":"string"},"isSTR":{"type":"boolean"},"hours":{"type":"number"},"entryCount":{"type":"number"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/breakdown":{"get":{"operationId":"getBreakdown","summary":"Break down a year of hours","description":"Year-scoped breakdown by property, category, and participant (from precomputed stats).","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"propertyType","in":"query","schema":{"type":"string","enum":["str","ltr"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"year":{"type":"number"},"totalHours":{"type":"number"},"entryCount":{"type":"number"},"byProperty":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}},"byCategory":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}},"byParticipant":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/goal-progress":{"get":{"operationId":"getGoalProgress","summary":"Progress toward the REPS hours goal","description":"Adapts to the user's case: LTR combined (500/750) and/or STR per-property (100/500).","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"year":{"type":"number"},"mode":{"type":"string","enum":["ltr","str","both"]},"ltr":{"type":"object","properties":{"goal":{"type":"number"},"hours":{"type":"number"},"label":{"type":"string"},"byParticipant":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"}}}}}},"str":{"type":"object","properties":{"goal":{"type":"number"},"properties":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"}}}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/dashboard":{"get":{"operationId":"getDashboard","summary":"Full year dashboard","description":"Goal + totals + breakdown by property / category / participant, in one document.","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"year":{"type":"number"},"goal":{"type":"number"},"totalHours":{"type":"number"},"ltrHours":{"type":"number"},"strHours":{"type":"number"},"entryCount":{"type":"number"},"byProperty":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}},"byCategory":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}},"byParticipant":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hours":{"type":"number"},"entryCount":{"type":"number"},"isSTR":{"type":"boolean"}}}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/stats":{"get":{"operationId":"getStats","summary":"Flexible stat query","description":"Totals over the precomputed stat tree with year / month / all-time grain and optional groupBy.","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"month","in":"query","schema":{"type":"integer","minimum":1,"maximum":12}},{"name":"allTime","in":"query","schema":{"type":"boolean"}},{"name":"groupBy","in":"query","schema":{"type":"string","enum":["none","property","category","participant","month"]}},{"name":"propertyId","in":"query","schema":{"type":"string"}},{"name":"participantId","in":"query","schema":{"type":"string"}},{"name":"propertyType","in":"query","schema":{"type":"string","enum":["str","ltr"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"scope":{"type":"object","properties":{"grain":{"type":"string","enum":["year","month","all_time"]},"year":{"type":"number"},"month":{"type":"number"},"groupBy":{"type":"string","enum":["none","property","category","participant","month"]},"propertyId":{"type":"string"},"participantId":{"type":"string"},"propertyType":{"type":"string","enum":["str","ltr"]}}},"totalHours":{"type":"number"},"ltrHours":{"type":"number"},"strHours":{"type":"number"},"entryCount":{"type":"number"},"groups":{"type":"array","items":{"type":"object"}}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/me":{"get":{"operationId":"whoami","summary":"Identity + entitlement of the authenticated user","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"uid":{"type":"string"},"email":{"type":"string"},"displayName":{"type":"string"},"plan":{"type":"string"},"entitlement":{"type":"string"},"propertiesType":{"type":"string","enum":["both","ltr","str"]}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}},"/user-settings":{"get":{"operationId":"getUserSettings","summary":"Read whitelisted user settings","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"propertiesType":{"type":"string","enum":["both","ltr","str"]},"internationalPropertiesEnabled":{"type":"boolean"}}}}}}}},"400":{"description":"Validation / bad request","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"403":{"description":"Forbidden scope / not Premium","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","required":["ok","code","message","requestId"],"properties":{"ok":{"type":"boolean","enum":[false]},"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}}}}}}}}