HydroForecast Time Series API (v2)

HydroForecast Time Series API (v2) is available and adds a significant amount of functionality over v1. It now allows:

  • Retrieving any forecast (HydroForecast Short-term, Seasonal, and the underlying weather forecasts) and observation series (satellite, snow, cleaned flow observations and more)
  • Retrieving any available forecast issue time, and multiple in a single request
  • Performing time aggregations (eg. daily average)
  • Converting rates to volumes
  • Accessing data from multiple sites within the same request
  • Time zone conversion

The easiest way to construct queries is to use HydroForecast Dashboard. To do so, select "View API v2 queries" from the plot title dropdown menu:

This will then show the exact underlying forecast and observation queries made to construct the plot.

If you have questions about how to construct a specific query, send a message to team@hydroforecast.com and we'd be happy to help.

Retrieve Forecasts: api/v2/timeseries/forecasts

This API route returns a list of one or more forecasts matching each query. Both weather and flow forecasts are available.

There are a few methods of selecting the forecast issue times to retrieve:

  • Providing a time range with issueTimeStartDate (inclusive) and issueTimeEndDate (exclusive). This is ideal for paging through an archive of forecasts.
  • Providing issueTimeAfterDate to retrieve only forecasts issued since a certain time. This is supports regularly syncing the latest forecasts into your database.
  • Providing a list timestamps with issueTimes to select specific forecast issues times.

Example response to a HydroForecast Short-term query:

{
  "data": [
    {
      "query": {
        "source": "hydroforecast-short-term",
        "columns": [
          "discharge_q0.01",
          "discharge_q0.025",
          "discharge_q0.05",
          "discharge_q0.1",
          "discharge_q0.25",
          "discharge_q0.5",
          "discharge_mean",
          "discharge_q0.75",
          "discharge_q0.9",
          "discharge_q0.95",
          "discharge_q0.975",
          "discharge_q0.99"
        ],
        "siteId": "example-site",
        "unitSystem": "US",
        "timeAggregation": "1D",
	"aggregationMethod": "mean",
        "rateVolumeMode": "rate",
        "issueTimeStartDate": "2023-04-27T18:00-07:00",
        "issueTimeEndDate": "2023-04-28T00:00-07:00"
      },
      "forecasts": [
        {
          "issueTime": "2023-04-27T21:53:12-07:00",
          "initializationTime": "2023-04-27T17:00:00-07:00",
          "validTimes": [
            "2023-04-27T17:00:00-07:00",
            "2023-04-28T00:00:00-07:00",
            "2023-04-29T00:00:00-07:00",
	    ...
            "2023-05-07T00:00:00-07:00"
          ],
          "validTimeRange": [
            "2023-04-27T17:00:00-07:00",
            "2023-05-07T18:00:00-07:00"
          ],
          "data": {
            "discharge_q0.01": [
              1180.1970707816395,
              1157.4593984650944,
              1214.754910444229,
	      ...
              981.0781552203101
            ],
	    ...
            "discharge_mean": [
              2671.1646739830181,
	      ...
            ],
	    ...
          }
        }
      ],
      "variables": {
        "discharge_q0.01": {
          "unit": "ft³/s"
        },
	...
        "discharge_mean": {
          "unit": "ft³/s"
        },
	...
      }
    }
  ]
}

Download a complete example response here: HydroForecast-v2-forecasts-API-response-example-hydroforecast-short-term-daily-average.json

Retrieve Observations: api/v2/timeseries/observations

This API route provides a time series of observations matching each query.

When this route is used with a weather forecast source it returns a time series created by joining the first N hours of each weather forecast in the requested date range. For example, if the forecast is issued every 6 hours it will join the first 6 hours of each forecast. 

Example response:

{
  "data": [
    {
      "query": {
        "source": "usgs",
        "columns": [
          "discharge"
        ],
        "siteId": "example-site",
        "unitSystem": "Metric",
        "rateVolumeMode": "rate",
        "startDate": "2023-04-28T00:00-07:00",
        "endDate": "2023-04-28T04:00-07:00"
      },
      "timestamps": [
        "2023-04-28T00:00:00-07:00",
        "2023-04-28T01:00:00-07:00",
        "2023-04-28T02:00:00-07:00",
        "2023-04-28T03:00:00-07:00"
      ],
      "dataTimeRange": [
        "2023-04-28T00:00:00-07:00",
        "2023-04-28T04:00:00-07:00"
      ],
      "data": {
        "discharge": [
          93.4455937536,
          92.029751424,
          90.9678696768,
          88.1361850176
        ]
      },
      "variables": {
        "discharge": {
          "unit": "m³/s"
        }
      }
    }
  ]
}

Example Usage

An example of fetching all forecasts issued since the most recently retrieved forecast. Code like this can be run regularly (every 2 hours) to pull all forecasts into a database you maintain.

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

url = "https://api.upstream.tech/api/v2/timeseries/forecasts"
api_key = "API-Key"
data = {
    "queries": [{
        "columns": ["discharge_q0.05", "discharge_q0.95", "discharge_q0.25", "discharge_q0.75", "discharge_mean"],
        "siteId": "example-site-id",
        "source": "hydroforecast-seasonal",
        "unitSystem": "US",
        "timeAggregation": "10D",
        "rateVolumeMode": "rate",
        # Fetch all forecasts issued more recently than this timestamp
        "issueTimeAfterDate": "2023-01-01T03:04+00:00"
    }]
}

response = requests.post(url, data=json.dumps(data), headers={"Authorization": api_key})

if response.status_code != 200:
  raise RuntimeError(f'{response.text} Status code: {response.status_code}')
else:
  print(response.json())