Introduction
Version: v1
The Tidetech Storm V1 API is a RESTful web service providing access to the latest data on tropical rotating storm activity for all ocean basins worldwide.
Forecasts are available out to 5 days/120 hours, or until the storm is expected to dissipate if less than 120 hours.
A list of currently active storms is provided via the /v1/active
endpoint.
Metadata for each active storm can be accessed from /v1/storm/{id}
and is updated 4 times/day for the Northern hemisphere, and 2 times/day for the Southern hemisphere. See the Metadata section for more details.
The GeoJSON representation of each storm contains: * Past storm tracks (lines) * Forecast storm tracks (lines) * Past storm positions and categories (points) * Forecast storm positions including storm categories, movement speed and direction at each forecast interval (0, 12, 24, 36, 48, 72, 96, 120 hours) * Forecast Error Boundaries for each forecast interval (lines) * Forecast Peak Gust Fields for the entire forecast (polygons)
Accessing the API
The API can be accessed at https://storm.tidetech.org/v1/
Accessing via browser
Explore the API by accessing the URLs provided in the response data. This is useful to get an understanding of the API structure, view metadata and GeoJSON features of currently active storms.
You can view active storms, metadata and GeoJSON in your browser by navigating to the index at https://storm.tidetech.org/v1/ and following the links provided.
Accessing via curl
curl
is a popular lightweight command line tool used to transfer data to or from servers. It is available for all major operating systems and can be used to test the shell
API request examples.
/v1/
curl --location --request GET https://storm.tidetech.org/v1/ \
--user "my_api_key:my_api_secret"
const axios = require("axios")
const apikey = "my_api_key";
const apisecret = "my_api_secret"
const url = "https://storm.tidetech.org/v1/"
axios.get(url, {
auth: {
username: apikey,
password: apisecret,
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
from requests import request
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/"
response = request("GET", url, auth=(apikey, apisecret))
print(response.json())
string apikey = "my_api_key";
string apisecret = "my_api_secret";
string url = "https://storm.tidetech.org/v1/";
var client = new RestClient(url);
client.Authenticator = new HttpBasicAuthenticator(apikey, apisecret);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var response = client.Execute(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
const (
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/"
)
func main() {
method := "GET"
client := &http.Client {}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.SetBasicAuth(apikey, apisecret)
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
Make sure to replace
my_api_key
andmy_api_secret
with your API Key and Secret.
Summary: API index
Description: The index endpoint lists the available API endpoints.
Endpoint /v1/
Method GET
Responses
Code | Description |
---|---|
200 | JSON object containing API index |
The above command returns json structured like this:
{
"links": {
"active": "https://storm.tidetech.org/v1/active"
}
}
/v1/active
curl --location --request GET https://storm.tidetech.org/v1/active \
--user "my_api_key:my_api_secret"
const axios = require("axios")
const apikey = "my_api_key";
const apisecret = "my_api_secret"
const url = "https://storm.tidetech.org/v1/active"
axios.get(url, {
auth: {
username: apikey,
password: apisecret,
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
from requests import request
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/active"
response = request("GET", url, auth=(apikey, apisecret))
print(response.json())
string apikey = "my_api_key";
string apisecret = "my_api_secret";
string url = "https://storm.tidetech.org/v1/active";
var client = new RestClient(url);
client.Authenticator = new HttpBasicAuthenticator(apikey, apisecret);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var response = client.Execute(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
const (
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/active"
)
func main() {
method := "GET"
client := &http.Client {}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.SetBasicAuth(apikey, apisecret)
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
Make sure to replace
my_api_key
andmy_api_secret
with your API Key and Secret.
Summary: Active storms index
Description: The active storms endpoint lists all currently active storms in all basins.
Endpoint /v1/active
Method GET
Responses
Code | Description |
---|---|
200 | JSON object containing active storms array |
The above command returns json structured like this: With active storms:
{
"data": [
{
"id": "202002E",
"name": "AMANDA",
"details": "https://storm.tidetech.org/v1/storm/202002E"
},
...other active storms
]
}
Without active storms:
json { "data": [] }
/v1/storm/{id}
curl --location --request GET https://storm.tidetech.org/v1/storm/202002E \
--user "my_api_key:my_api_secret"
const axios = require("axios")
const apikey = "my_api_key";
const apisecret = "my_api_secret"
const url = "https://storm.tidetech.org/v1/storm/202002E"
axios.get(url, {
auth: {
username: apikey,
password: apisecret,
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
from requests import request
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/storm/202002E"
response = request("GET", url, auth=(apikey, apisecret))
print(response.json())
string apikey = "my_api_key";
string apisecret = "my_api_secret";
string url = "https://storm.tidetech.org/v1/storm/202002E";
var client = new RestClient(url);
client.Authenticator = new HttpBasicAuthenticator(apikey, apisecret);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var response = client.Execute(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
const (
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/storm/202002E"
)
func main() {
method := "GET"
client := &http.Client {}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.SetBasicAuth(apikey, apisecret)
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
Make sure to replace
my_api_key
andmy_api_secret
with your API Key and Secret.
Summary: Storm metadata
Description: The /v2/storm/{id} endpoint returns the most recent metadata for that storm.
Endpoint /v1/storm/{id}
Method GET
Responses
Code | Description |
---|---|
200 | JSON object containing storm metadata |
The above command returns json structured like this:
{
"data": {
"id": "202002E",
"advisory": "2020-05-31T15:00:00Z",
"is_active": true,
"name": "AMANDA",
"basin": "NEP",
"category": "ts",
"forecast_hours": 72,
"geojson": "https://storm.tidetech.org/v1/storm/202002E/features",
"event_number": 2,
"position": [
-90.3,
14.7
],
"movement": {
"KPH": 17,
"MPH": 10,
"KTS": 9,
"bearing": 6
},
"max_observed_category": "ts",
"max_forecast_category": "ts",
"name_list": [
"02E",
"AMANDA"
],
"advisory_list": [
"2020-05-31T03:00:00Z",
"2020-05-31T09:00:00Z",
"2020-05-31T15:00:00Z"
]
}
}
Parameters
Name | Located in | Description | Required | Type |
---|---|---|---|---|
id | path | storm id | Yes | string |
/v1/storm/{id}/features
curl --location --request GET https://storm.tidetech.org/v1/storm/202002E/features \
--user "my_api_key:my_api_secret"
const axios = require("axios")
const apikey = "my_api_key";
const apisecret = "my_api_secret"
const url = "https://storm.tidetech.org/v1/storm/202002E/features"
axios.get(url, {
auth: {
username: apikey,
password: apisecret,
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
from requests import request
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/storm/202002E/features"
response = request("GET", url, auth=(apikey, apisecret))
print(response.json())
string apikey = "my_api_key";
string apisecret = "my_api_secret";
string url = "https://storm.tidetech.org/v1/storm/202002E/features";
var client = new RestClient(url);
client.Authenticator = new HttpBasicAuthenticator(apikey, apisecret);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
var response = client.Execute(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
const (
apikey = "my_api_key"
apisecret = "my_api_secret"
url = "https://storm.tidetech.org/v1/storm/202002E/features"
)
func main() {
method := "GET"
client := &http.Client {}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.SetBasicAuth(apikey, apisecret)
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
Make sure to replace
my_api_key
andmy_api_secret
with your API Key and Secret.
Summary: Storm GeoJSON representation
Description: The /v2/storm/{id}/features endpoint returns the most recent GeoJSON FeatureCollection for that storm.
Endpoint /v1/storm/{id}/features
Method GET
Responses
Code | Description |
---|---|
200 | JSON object containing storm metadata |
The above command returns json structured like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-91.1,
12.3
],
[
-90.6,
13
]
]
},
"properties": {
"featureType": "stormTrack-past",
"id": "202002E",
"name": "AMANDA",
"basin": "NEP",
"intensity": "td",
"color": "#00ccff",
"opacity": 221
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-90.6,
13
],
[
-90.4,
13.8
]
]
},
"properties": {
"featureType": "stormTrack-past",
"id": "202002E",
"name": "AMANDA",
"basin": "NEP",
"intensity": "td",
"color": "#00ccff",
"opacity": 221
}
}
],
...more storm features
}
Parameters
Name | Located in | Description | Required | Type |
---|---|---|---|---|
id | path | storm id | Yes | string |
Metadata
key | value |
---|---|
id |
The storm ID. This ID is unique across the API. |
advisory |
The UTC datetime of the most recent advisory for this storm. |
is_active |
Whether or not the storm is currently active. |
name |
The storm name. |
basin |
The ocean basin in which the storm is currently active. |
category |
The tropical cyclone classification of the storm as at the time of advisory. |
forecast_hours |
The number of hours in the forecast, based on the estimated duration of the storm, up to 120 hours. |
geojson |
Link to the GeoJSON representation of the storm forecast. |
event_number |
The seasonal event number of the storm within a basin. |
position |
The coordinates of the storm at the time of advisory. |
movement |
The movement speed and bearing at the time of advisory. |
max_observed_category |
The maximum tropical storm classification reached by the storm. |
max_forecast_category |
The maximum tropical storm classification forecasted for the storm. |
name_list |
All names assigned to a storm. Eg. ["TWENTYTHREE", "WALLACE"] . |
advisory_list |
Record of advisory dates. |
Basin and Sub-basin Codes
Basins
code | description |
---|---|
ATL | North Atlantic |
NEP | Northeast Pacific |
NWP | Northwest Pacific |
SWP | Southwest Pacific |
SIO | South Indian Ocean |
NIO | North Indian Ocean |
Sub-basins
code | description |
---|---|
N | North Atlantic |
W | Northwest Pacific |
A | Arabian Sea |
B | Bay of Bengal |
E | Northeast Pacific |
C | Central Pacific |
P | Southwest Pacific |
S | South Indian |
Storm Categories
strength | category | color | speed kts | speed mph | speed kph |
---|---|---|---|---|---|
Tropical Depression | TD | #00CCFF |
<34 | <39 | <63 |
Tropical Storm | TS | #00FF00 |
34-63 | 39-73 | 63-118 |
Hurricane | Cat1 | #FFFF00 |
64-82 | 74-95 | 119-153 |
Hurricane | Cat2 | #FFCC00 |
83-95 | 96-110 | 154-177 |
Intense Hurricane | Cat3 | #FF6600 |
96-112 | 111-129 | 178-208 |
Intense Hurricane | Cat4 | #FF0000 |
113-136 | 130-156 | 209-251 |
Intense Hurricane | Cat5 | #CC00CC |
>136 | >156 | >251 |
Errors
The Tidetech API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The requested resource is hidden for administrators only. |
404 | Not Found -- The specified resource could not be found. |
405 | Method Not Allowed -- You tried to access a resource with an invalid method. |
410 | Gone -- The resource requested has been removed from our servers. |
418 | I'm a teapot. |
429 | Too Many Requests. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |