HydroForecast Get Forecasts API (v1 - legacy)

GET /forecasts/<siteId>

This API route has been superseded by the more capable HydroForecast Time Series API (v2). This route will continue to be supported for the time being. New users are encouraged to use the Time Series (v2) API.

GET /api/v1/forecasts/<siteId>

URL Parameter
* siteId - The site identifier for your site of interest provided to you by the HydroForecast team.

Query Parameters
* type - The forecast type, one of "short-term" or "seasonal". Required.
* startDate - Retrieve forecasts where forecastDate >= startDate. Optional.
* endDate - Retrieve forecasts where forecastDate < endDate. Optional.
* updatedSince - Filter forecasts where updatedAt > updatedSince. Optional.
* sort - Order forecasts by forecastDate. Value must be one of "asc" or "desc". Optional, defaults to "asc".
* format - The format of the response. Value must be one of "json" or "csv". Optional, defaults to "json".
* page - The page of results to retrieve. Optional, defaults to 1.
* perPage - The number of forecasts to return in each page. Optional, defaults to 25 and limited to a maximum of 25.

Dates should be formatted as ISO 8601 date strings including a timezone offset. For example, 2021-01-01T01:23:45-08:00 or 2021-01-01T00:00:00Z.

Example JSON response:

{
  "page": 1,
  "hasNextPage": true,
  "data": {
    "siteId": "example-site",
    "type": "short-term",  # or "seasonal"
    "units": "cms"   # or "cfs"
    "forecasts": [
      {
        "forecastDate": "2021-01-01T00:00:00+00:00",
        "updatedAt": "2021-01-01T01:23:45+00:00",
        "data": {
          "datetime": [
            "2021-01-01T00:00:00+00:00",
            "2021-01-01T01:00:00+00:00",
            "2021-01-01T02:00:00+00:00",
            ...
          ],
          # The 0.01 quantile forecast - the value likely to be exceeded 99% of the time
          "discharge_q0.01": [ 
            1.0, 2.0, 1.5, ...
          ],
          "discharge_q0.025": [
            ...
          ],
          "discharge_q0.05": [
            ...
          ],
          "discharge_q0.1": [
            ...
          ],
          "discharge_q0.25": [
            ...
          ],
          # This key contains HydroForecast's estimate of the most likely forecast value
          "discharge_q0.5": [
            ...
          ],
          "discharge_q0.75": [
            ...
          ],
          "discharge_q0.9": [
            ...
          ],
          "discharge_q0.95": [
            ...
          ],
          "discharge_q0.975": [
            ...
          ],
          "discharge_q0.99": [
            ...
          ]
        }
      },
      {
        "forecastDate": "2021-01-02T00:00:00+00:00",
        "updatedAt": "2021-01-02T01:23:45+00:00",
        "data": { ... }
      }
    ]
  }
}

Example CSV response

{"siteId": "example-site", "type": "short-term", "units": "cms", "page": 1, "hasNextPage": true}
issueTime,validTime,updatedAt,discharge_q0.01,discharge_q0.025,discharge_q0.05,discharge_q0.1,discharge_q0.25,discharge_q0.5,discharge_q0.75,discharge_q0.9,discharge_q0.95,discharge_q0.975,discharge_q0.99
2021-01-01T00:00:00+00:00,2021-01-01T00:00:00+00:00,2021-01-01T00:30:00+00:00,12.92,13.57,14.52,16.00,18.93,22.51,26.70,32.74,35.92,39.44,46.00
2021-01-01T00:00:00+00:00,2021-01-01T01:00:00+00:00,2021-01-01T00:30:00+00:00,12.46,13.43,14.27,15.87,18.56,22.23,26.42,32.28,35.66,39.12,45.15
2021-01-01T00:00:00+00:00,2021-01-01T02:00:00+00:00,2021-01-01T00:30:00+00:00,12.32,13.36,14.14,15.82,18.36,22.06,26.28,31.99,35.50,39.07,44.94

Example File Downloads

Example CSV downloads:

HydroForecast_short-term_example.csv

HydroForecast_seasonal_example.csv

Example JSON downloads:

HydroForecast_short-term_example.json

HydroForecast_seasonal_example.json


Example Usage

Retrieve the latest forecast

Curl

# Retrieve in JSON format
curl 'https://api.hydroforecast.com/api/v1/forecasts/example-site-id?type=short-term&sort=desc&perPage=1' -H 'Authorization: API-Token'

# Retrieve in CSV format
curl 'https://api.hydroforecast.com/api/v1/forecasts/example-site-id?type=short-term&sort=desc&perPage=1&format=csv' -H 'Authorization: API-Token' --remote-name --remote-header-name

Python

import requests  # Requests library to make HTTP calls. Install with `pip install requests`

site_id = 'example-site-id'
forecast_type = 'short-term'
api_token = 'API-Token'

response = requests.get(f'https://api.hydroforecast.com/api/v1/forecasts/{site_id}',
                        params={'type': forecast_type, 'sort': 'desc', 'perPage': 1},
                        headers={'Authorization': api_token})
if response.status_code != 200:
  raise RuntimeError(f'{response.text} Status code: {response.status_code}')
response_json = response.json()

# Visualize the forecast
import pandas as pd  # pip install pandas
import matplotlib.pyplot as plt  # pip install matplotlib

for forecast in response_json['data']['forecasts']:
  forecast_data = pd.DataFrame(forecast['data']).set_index('datetime')
  forecast_data.plot()
  plt.show()
Ongoing forecast retrieval

Python

import requests

site_id = 'example-site-id'
forecast_type = 'short-term'
api_token = 'API-Token'

# Retrieve the updatedAt time of the latest forecast already saved 
# in your system or None if this is the first time accessing forecasts.
updated_since = get_latest_forecast_updated_date() 
page = 1
has_next_page = True

while has_next_page:
  response = requests.get(f'https://api.hydroforecast.com/api/v1/forecasts/{site_id}',
                          params={
                            'type': forecast_type,
                            'updatedSince': updated_since,
                            'page': page
                          },
                          headers={'Authorization': api_token})
  response.raise_for_status()
  response_json = response.json()

  has_next_page = response_json['hasNextPage']
  page += 1

  if len(response_json['data']['forecasts']) > 0:
    # Save forecasts to your system
    save_forecasts(response_json)

    if not has_next_page:
      print(f"Done retrieving new forecasts at {site_id}. " 
            f"Latest forecast date retrieved: {response_json['data']['forecasts'][-1]['forecastDate']}")
  else:
    print(f'All forecasts at {site_id} updated since {updated_since} have already been retrieved.')