{"openapi":"3.1.0","info":{"title":"Joburg water record: open API","description":"Read-only JSON over what Johannesburg Water (JW) reported about its reservoirs and towers since March 2025, read from JW's status boards and notices. No key. Licence: CC BY 4.0 for this compilation and its readings. The facts are what Johannesburg Water (JW) reported on its status boards and notices: credit Johannesburg Water as the source.","version":"1"},"paths":{"/api/v1/suburbs":{"get":{"summary":"Suburbs","description":"Every suburb with a page: its id (used in every other suburb address),\nits everyday name, and whether JW's pages link it to a supply (coverage).","operationId":"suburbs_api_v1_suburbs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/suburbs/{slug}":{"get":{"summary":"Suburb","description":"One suburb: the reservoirs and towers JW links it to, how JW links each\n(with JW's own source links), and for each supply the days per year JW\nreported it at no water or critically low, against the city's median\nsupply. A suburb draws on all its supplies at once.","operationId":"suburb_api_v1_suburbs__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/suburbs/{slug}/history":{"get":{"summary":"Suburb History","description":"A suburb's history, one row per supply per day: the worst level JW\nreported for the supply that day, in JW's terms and in a plain sentence\n(wording). A day with no JW board is a gap (level \"no_report\"): it is not a\nnormal day. Optional 'from' and 'to' (YYYY-MM-DD) narrow the days.","operationId":"suburb_history_api_v1_suburbs__slug__history_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/supplies":{"get":{"summary":"Supplies","description":"Every reservoir, tower, pump station and direct feed JW names, with the\nsystems JW lists it under.","operationId":"supplies_api_v1_supplies_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/supplies/{asset_id}":{"get":{"summary":"Supply","description":"One supply: what JW's own page says about it (capacity, demand,\nstorage), its latest JW report, how long it has been on the boards, the\ndays per year and per month JW reported it at no water or critically low\n(with the same month a year earlier where comparable), how long its last\noutages lasted, its rank in the city, and the suburbs JW links to it.","operationId":"supply_api_v1_supplies__asset_id__get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/supplies/{asset_id}/history":{"get":{"summary":"Supply History","description":"A supply's history, one row per day: the worst level JW reported, a\nplain sentence (wording), bypass, and each status as JW printed it that day\n(time and text). A day with no JW board is a gap (level \"no_report\"), not a\nnormal day. Optional 'from' and 'to' (YYYY-MM-DD) narrow the days.","operationId":"supply_history_api_v1_supplies__asset_id__history_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/supplies/{asset_id}/reports":{"get":{"summary":"Supply Reports","description":"The last statuses JW printed for a supply, newest first (default 50, at\nmost 500): the board time, the level, the text as JW printed it, and links\nto JW's own post and board image.","operationId":"supply_reports_api_v1_supplies__asset_id__reports_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}},{"name":"n","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/supplies/{asset_id}/outages":{"get":{"summary":"Supply Outages","description":"Every outage JW's boards show for a supply, newest first: a run of\nreports at no water or critically low, with its start, end and length in\nhours. 'censored' means JW reported no end, so the length is a minimum.\n'no_board_days' counts days with no board inside it (C41: up to 4 such\ndays between two outage reports do not end it); JW reported nothing\nfor those days.","operationId":"supply_outages_api_v1_supplies__asset_id__outages_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/supplies/{asset_id}/notices":{"get":{"summary":"Supply Notices","description":"Each end date JW stated in a notice that concerns this supply, against\nthe first board after it on which JW reported the supply back (supplying\nfairly or better, off bypass). 'delta_hours' is how late; 'censored' means\nJW has not reported it back since.","operationId":"supply_notices_api_v1_supplies__asset_id__notices_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/systems":{"get":{"summary":"Systems","description":"JW's supply systems as JW names them, with how many supplies each lists.","operationId":"systems_api_v1_systems_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/systems/{slug}":{"get":{"summary":"System","description":"One JW supply system: its supplies, and per year the share of board\nrows printed under it that announced a scheduled overnight closure.","operationId":"system_api_v1_systems__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/regions":{"get":{"summary":"Regions","description":"JW's seven operational regions (A to G), with how many suburbs JW's\nnotices place in each.","operationId":"regions_api_v1_regions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/regions/{region}":{"get":{"summary":"Region","description":"One JW region: the suburbs JW's notices place in it, and the supplies JW\nlinks to those suburbs.","operationId":"region_api_v1_regions__region__get","parameters":[{"name":"region","in":"path","required":true,"schema":{"type":"string","title":"Region"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/city/ranking/{year}":{"get":{"summary":"Ranking","description":"Every supply ranked within its kind (reservoir, tower) by the days in a\nyear JW reported it at no water or critically low (rank 1 is the most),\nwith the city's median supply. Keyed by kind, then supply id.","operationId":"ranking_api_v1_city_ranking__year__get","parameters":[{"name":"year","in":"path","required":true,"schema":{"type":"string","title":"Year"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/maintenance":{"get":{"summary":"Maintenance","description":"Rand Water's maintenance windows the record covers, by start day.","operationId":"maintenance_api_v1_maintenance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/maintenance/{date}":{"get":{"summary":"Maintenance Window","description":"One maintenance window (by its start day, YYYY-MM-DD): how many supplies\nJW reported out around it, the median and slowest days until JW reported\nthem back, and each supply's days. Supplies on bypass before the window\ncannot be counted as recovered and are listed apart.","operationId":"maintenance_window_api_v1_maintenance__date__get","parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","title":"Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/releases":{"get":{"summary":"Releases","description":"Every dated release of the record, newest first. Cite a figure with its\nrelease id. Where a bulk download (CSV and JSONL, with a manifest of row\ncounts and sha256 checksums) exists, 'bulk' links to it.","operationId":"releases_api_v1_releases_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/search":{"get":{"summary":"Search","description":"Suburb names like the query, best first (at most 10), with a score from\n0 to 1. Use the id in the suburb addresses.","operationId":"search_api_v1_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"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"}}}}