{"openapi":"3.1.0","info":{"title":"River Watch","description":"Water level at Tessaban Muang Pathum, read from a public CCTV staff gauge by computer vision. Informational only — not an official flood warning.","contact":{"name":"Kriddanai Roonguthai (Dang Coffee Roaster)","url":"https://flood.dangcoffeeroaster.com/"},"license":{"name":"MIT License","url":"https://flood.dangcoffeeroaster.com/license"},"version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/latest":{"get":{"summary":"Api Latest","operationId":"api_latest_api_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/readings":{"get":{"summary":"Api Readings","operationId":"api_readings_api_readings_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"default":500,"title":"Limit"}},{"name":"include_experimental","in":"query","required":false,"schema":{"type":"boolean","description":"include the first hour of readings, which were read by a vision model and are metres out","default":false,"title":"Include Experimental"},"description":"include the first hour of readings, which were read by a vision model and are metres out"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/summary":{"get":{"summary":"Api Summary","operationId":"api_summary_api_summary_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":3,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reading/{reading_id}":{"get":{"summary":"Api Reading","operationId":"api_reading_api_reading__reading_id__get","parameters":[{"name":"reading_id","in":"path","required":true,"schema":{"type":"integer","title":"Reading Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/image/{reading_id}":{"get":{"summary":"Api Image","operationId":"api_image_api_image__reading_id__get","parameters":[{"name":"reading_id","in":"path","required":true,"schema":{"type":"integer","title":"Reading Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/overlay/{reading_id}":{"get":{"summary":"Api Overlay","description":"The frame with the calibration grid and detected waterline drawn on it.","operationId":"api_overlay_api_overlay__reading_id__get","parameters":[{"name":"reading_id","in":"path","required":true,"schema":{"type":"integer","title":"Reading Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/thumb/{reading_id}.jpg":{"get":{"summary":"Api Thumb","operationId":"api_thumb_api_thumb__reading_id__jpg_get","parameters":[{"name":"reading_id","in":"path","required":true,"schema":{"type":"integer","title":"Reading Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/frames":{"get":{"summary":"Api Frames","description":"Frames available for playback, oldest first.","operationId":"api_frames_api_frames_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/card.png":{"get":{"summary":"Latest Card","description":"The analysis card for the newest reading — the LINE message's hero.","operationId":"latest_card_card_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/card/{reading_id}.png":{"get":{"summary":"Card","operationId":"card_card__reading_id__png_get","parameters":[{"name":"reading_id","in":"path","required":true,"schema":{"type":"integer","title":"Reading Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/latest.jpg":{"get":{"summary":"Latest Jpg","description":"Stable URL for the newest frame — what the LINE message points at.","operationId":"latest_jpg_latest_jpg_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/latest-overlay.png":{"get":{"summary":"Latest Overlay","description":"Stable URL for the newest frame with the measurement drawn on it.","operationId":"latest_overlay_latest_overlay_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"Dashboard","operationId":"dashboard__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/history":{"get":{"summary":"History","operationId":"history_history_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":8760,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/timelapse":{"get":{"summary":"Timelapse","operationId":"timelapse_timelapse_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license":{"get":{"summary":"License Page","description":"The licence, served from the same file that ships in the repository.","operationId":"license_page_license_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api":{"get":{"summary":"Api Docs","description":"Public API documentation, aimed at whoever wants to reuse the data.","operationId":"api_docs_api_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/prompt":{"get":{"summary":"Prompt Page","description":"A copy-paste brief for anyone wanting to build this for their own camera.\n\nDeliberately generic: it carries the method and the mistakes worth avoiding,\nnot this deployment's configuration.","operationId":"prompt_page_prompt_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/station":{"get":{"summary":"Api Station","description":"Everything a reuser needs to interpret the numbers correctly.","operationId":"api_station_api_station_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/readings.csv":{"get":{"summary":"Api Readings Csv","description":"The same readings as CSV, for spreadsheets and analysis tools.","operationId":"api_readings_csv_api_readings_csv_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":8760,"minimum":1,"default":168,"title":"Hours"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":1,"default":5000,"title":"Limit"}},{"name":"include_experimental","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Experimental"}}],"responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/poster.png":{"get":{"summary":"Api Poster","description":"Printable A4 notice for residents, regenerated on demand.","operationId":"api_poster_poster_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/qr.png":{"get":{"summary":"Api Qr","description":"QR code for the site, for anyone making their own notice.","operationId":"api_qr_qr_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}