{"components":{"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","scheme":"bearer","type":"http"}}},"info":{"title":"kval API","version":"1.1.0"},"openapi":"3.0.3","paths":{"/auth/login":{"post":{"description":"Returns a short-lived JWT for API calls. No self-signup.","requestBody":{"content":{"application/json":{"schema":{"properties":{"password":{"format":"password","type":"string"},"username":{"type":"string"}},"required":["username","password"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"token":{"type":"string"},"user_id":{"type":"integer"},"username":{"type":"string"}},"type":"object"}}},"description":"Login success"},"401":{"description":"Invalid credentials"},"403":{"description":"Password not set"}},"summary":"Login with username and password"}},"/auth/tokens":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"jti":{"type":"string"},"label":{"nullable":true,"type":"string"}},"type":"object"},"type":"array"}}},"description":"Array of token metadata"}},"security":[{"bearerAuth":[]}],"summary":"List current user's tokens"},"post":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"label":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"meta":{"properties":{"created_at":{"format":"date-time","type":"string"},"jti":{"type":"string"},"label":{"nullable":true,"type":"string"}},"type":"object"},"token":{"type":"string"}},"type":"object"}}},"description":"Token created"}},"security":[{"bearerAuth":[]}],"summary":"Create a new token for the current user"}},"/auth/tokens/{jti}":{"delete":{"parameters":[{"in":"path","name":"jti","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"},"404":{"description":"Not found"}},"security":[{"bearerAuth":[]}],"summary":"Revoke a token"}},"/keyvalue":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}},"description":"Map of keys to JSON values"}},"security":[{"bearerAuth":[]}],"summary":"List all keys and values for the authenticated user"}},"/keyvalue/{key}":{"delete":{"parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Successfully deleted"},"404":{"description":"Key not found"}},"security":[{"bearerAuth":[]}],"summary":"Delete a key and its value"},"get":{"parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"Successful retrieval"}},"security":[{"bearerAuth":[]}],"summary":"Retrieve the value for a key"},"post":{"parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"example_num":999,"example_str":"lorem ipsum"},"schema":{"additionalProperties":true,"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"Successfully stored"}},"security":[{"bearerAuth":[]}],"summary":"Store a value for a key"}},"/status":{"get":{"responses":{"200":{"content":{"application/json":{"example":{"code":200,"status":"OK"},"schema":{"properties":{"code":{"type":"integer"},"status":{"type":"string"}},"type":"object"}}},"description":"Service is healthy"},"500":{"content":{"application/json":{"example":{"code":500,"status":"down"},"schema":{"properties":{"code":{"type":"integer"},"status":{"type":"string"}},"type":"object"}}},"description":"Cannot connect to database"}},"summary":"Service status"}}},"servers":[{"url":"https://kval.treadstone.dev/"}]}
