{"openapi":"3.1.0","info":{"title":"Laundry Control API","version":"1.0.0","description":"A token-hiding SmartThings Devices API wrapper with development PAT and production OAuth 2.0 authentication. Authentication state is isolated in an encrypted HttpOnly browser cookie."},"servers":[{"url":"https://quantstruct.com"}],"paths":{"/app/api/health":{"get":{"summary":"Check the local server","responses":{"200":{"description":"Server is running"}}}},"/app/api/bootstrap":{"get":{"summary":"Get connection and device-selection state","responses":{"200":{"description":"Controller bootstrap state"}}}},"/app/api/auth/token":{"post":{"summary":"Validate and hold a SmartThings PAT in server memory","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","writeOnly":true}}}}}},"responses":{"200":{"description":"Token validated"},"401":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Forget the in-memory token","responses":{"200":{"description":"Token forgotten"}}}},"/app/api/auth/mode":{"post":{"summary":"Switch the active SmartThings authentication provider","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["development","production"]}}}}}},"responses":{"200":{"description":"Authentication mode changed"},"400":{"$ref":"#/components/responses/Error"}}}},"/app/api/auth/oauth/start":{"get":{"summary":"Begin SmartThings OAuth authorization","responses":{"302":{"description":"Redirect to SmartThings authorization"},"503":{"$ref":"#/components/responses/Error"}}}},"/app/api/auth/oauth/config":{"post":{"summary":"Encrypt and save SmartThings OAuth app credentials","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["clientId","clientSecret"],"properties":{"clientId":{"type":"string","writeOnly":true},"clientSecret":{"type":"string","writeOnly":true}}}}}},"responses":{"200":{"description":"OAuth app settings encrypted into this browser session"},"400":{"$ref":"#/components/responses/Error"}}}},"/app/api/auth/oauth/disconnect":{"post":{"summary":"Delete the locally stored OAuth tokens","responses":{"200":{"description":"OAuth connection removed"},"503":{"$ref":"#/components/responses/Error"}}}},"/app/oauth/callback":{"get":{"summary":"Receive the SmartThings OAuth authorization callback","parameters":[{"name":"code","in":"query","schema":{"type":"string"}},{"name":"state","in":"query","schema":{"type":"string"}},{"name":"error","in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect to the control page with callback result"}}}},"/app/api/devices":{"get":{"summary":"Discover compatible washers and dryers","responses":{"200":{"description":"Compatible SmartThings devices"},"401":{"$ref":"#/components/responses/Error"}}}},"/app/api/devices/select":{"post":{"summary":"Select the washer and dryer controlled by this app","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["washerId","dryerId"],"properties":{"washerId":{"type":"string"},"dryerId":{"type":"string"}}}}}},"responses":{"200":{"description":"Selection saved"},"400":{"$ref":"#/components/responses/Error"}}}},"/app/api/appliances":{"get":{"summary":"Read normalized washer and dryer state","responses":{"200":{"description":"Normalized appliance states"},"401":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/app/api/appliances/{kind}/actions":{"post":{"summary":"Start, pause, or stop an appliance","parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["washer","dryer"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["start","pause","stop"]}}}}}},"responses":{"202":{"description":"SmartThings accepted the command"},"409":{"$ref":"#/components/responses/Error"}}}},"/app/api/activity":{"get":{"summary":"Read recent local connection and command events","responses":{"200":{"description":"Recent activity"}}}},"/app/api/openapi.json":{"get":{"summary":"Download this OpenAPI document","responses":{"200":{"description":"OpenAPI document"}}}}},"components":{"responses":{"Error":{"description":"Structured API error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}