Currently we offer free or individual API accounts. Free access is restricted in terms of the time series and resolutions that can be queried. Moreover, stricter limits apply and it is not possible to choose the time period for the values to be queried.
However, it is still possible to obtain complete, gapless time series if the requests are issued periodically within the limits.
For a summary of the current capabilities of your account, check out the overview.
If the free access does not meet your needs, please feel free to contact us.
POST or GET request method can be used via HTTPS only connection.
A security token must be included in every request. The prefered method is to include the token as authorization header.
Example header:
Authorization: Bearer your-token
Alternatively the token can be included as key value pair in the JSON object sent by the POST method.
Example POST request:{
"token": "your-token"
}
Or via token url paramter using the GET method.
Example GET request:
https://api.gridradar.net/?token=your-token
If exceeded, a corresponding message and error code 429 is returned. Limits apply to each account and metric individually.
The following example uses the curl command to POST a JSON object to the /help
endpoint forcing a response in HTML format.
curl -i -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{"format":"html"}' \
https://api.gridradar.net/help
The API description below is the HTML response to this API call with some custom CSS style attached.
/ | Test security token |
/help | Returns this API short description. |
/attrib | Shows account infos. |
/metrics | List of metric names permitted for the transmitted security token. |
/alerts | Alert management endpoint. |
/search | List of metric names (grafana compatibility). |
/pmus | List of phasor measurement units permitted for the transmitted security token. |
/areas | List of synchronous grid areas permitted for the transmitted security token. |
/tso | List of available transmission system operators. |
/ranges | List of timestamps for the first and last value of the phasor measurement units. |
/aggr_functions | Available aggregation functions and selectors |
/aggregations | Available aggregation units |
/formats | Available response formats |
/ts_formats | Available timestamp formats |
/fill | Available fill actions |
/query | Time series data endpoint. |
help | Returns a descriptive string for the called endpoint |
format | Sets the response format (e.g.: format=json) |
token | An alternative option if the security token cannot be included as 'Authorization: Bearer [token]' header |
/help?html | Shows a HTML version of this help | ||||||||||||||||||||||||
/metrics | |||||||||||||||||||||||||
| |||||||||||||||||||||||||
/pmus | |||||||||||||||||||||||||
| |||||||||||||||||||||||||
/areas?all | Lists all available synchronous grid areas. | ||||||||||||||||||||||||
/search?ep | Returns the result of supported endpoints as a list. Can be combined with the endpoint specific arguments 'all' and 'filter'. (e.g.: search?ep=metrics&filter=60hz) If no 'ep' parameter value is set, a list of supported endpoints is returned. Not specifying the 'ep' parameter at all is equivalent to ep=metrics. | ||||||||||||||||||||||||
/ranges?all | Lists the data time range of all existing phasor measurement units | ||||||||||||||||||||||||
/query | |||||||||||||||||||||||||
| |||||||||||||||||||||||||
/alerts | |||||||||||||||||||||||||
|
200 | Request was successful |
400 | Invalid api call (e.g.:malformed query arguments) |
401 | Failed authentication (e.g.: unknown security token) |
403 | Lack of permission for the transmitted security token to process the request |
408 | Timeout |
429 | Some limit exceeded |
500 | Unexpected errors |
The default response format is JSON. The example below calls the /formats
endpoint and does not use any parameters. The response is a JSON object containing all available response format keys and a corresponding description line.
import requests
url = 'https://api.gridradar.net/formats'
headers = {
'Content-type': 'application/json',
'Authorization': 'Bearer your-token'
}
response = requests.post(url, headers=headers)
print(response.content)
JSON response:
{
"columns":["response format","description"],
"data":[
["json","Json object"],
["csv","Comma separated list"],
["xml","XML document"],
["html","HTML Table"]
]
}
Repeating the previous example but with the format parameter specified results in the following responses.
Requesting CSV response:json_request = '{"format":"csv"}'
response = requests.post(url, data=json_request, headers=headers)
CSV response:
response format,description
json,Json object
csv,Comma separated list
xml,XML document
html,HTML Table
HTML response:
<table border="1" class="dataframe" id="formats">
<thead>
<tr style="text-align: right;">
<th>response format</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>json</td>
<td>Json object</td>
</tr>
<tr>
<td>csv</td>
<td>Comma separated list</td>
</tr>
<tr>
<td>xml</td>
<td>XML document</td>
</tr>
<tr>
<td>html</td>
<td>HTML Table</td>
</tr>
</tbody>
</table>
XML response:
<?xml version='1.0' encoding='utf-8'?>
<data>
<row>
<response_format>json</response_format>
<description>Json object</description>
</row>
<row>
<response_format>csv</response_format>
<description>Comma separated list</description>
</row>
<row>
<response_format>xml</response_format>
<description>XML document</description>
</row>
<row>
<response_format>html</response_format>
<description>HTML Table</description>
</row>
</data>
Free users currently have permissions to call the /query
endpoint using the metric keys frequency-ucte-median-1s
and net-time
without the time range arguments from
and to
.
The start timestamp is calculated based on the timestamp of the last value in the previous query response.
The maximum time range a response may contain is one hour.
frequency-ucte-median-1s
{
"metric":"frequency-ucte-median-1s"
}
The example above is the short form of the next request JSON object.
{
"metric":"frequency-ucte-median-1s",
"format":"json",
"ts":"rfc3339",
"aggr": "1s"
}
The following curl
command example returns the minimum frequency per minute
curl -i -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{"metric":"frequency-ucte-median-1s", "func":"min", "aggr":"1m"}' \
https://api.gridradar.net/query
Example arguments for the metric key: net-time
{
"metric":"net-time"
}
The net-time
metric returns the deviation from UTC time in seconds. The previous example is the short form of the request below.
{
"metric":"net-time",
"format":"json",
"ts":"rfc3339",
"aggr":"1s",
"fill":"none"
}
The next curl
command uses the GET method to query the net time.
curl 'https://api.gridradar.net/query?token=your-token&metric=net-time'
Individual users have permission to query the /query
endpoint with additional metric name keys, where the time range arguments from
and to
can also be used.
For certain metrics it may be necessary to specify special arguments, such as pmus
for the metrics frequency
and phase-angle
to define a selection of measuring stations.
Depending on the agreement, access can be subject to different limitations. Accessibility of measurement stations can be extended from single locations, whole countries up to the complete network. The minimum query interval can be reduced to 3 seconds with a maximum resolution of 100ms.
#!/usr/bin/python3
import requests
import json
import pprint
## Request and header parameters
token = 'your-token'
url = 'https://api.gridradar.net/query'
headers = {
'Content-type': 'application/json',
'Authorization': 'Bearer '+token
}
## API query parameters
request = {
"metric":"frequency",
"pmus":"neustadt,dresden",
"from":"2021-05-26T02:36:17.3Z",
"to":"2021-05-26T02:36:17.6Z",
"aggr":"100ms",
"format":"json",
"ts":"rfc3339"
}
## Converting the Python dictionary to a JSON string
json_request = json.dumps(request)
## Request execution and response reception
response = requests.post(url, data=json_request, headers=headers)
## Converting the JSON response string to a Python dictionary
result_dict = json.loads(response.content)
## Pretty print response dictionary
pprint.pprint(result_dict)
The response contains two time series:
NOTE: The JSON response format of all endpoints is compatible with the Grafana JSON datasource plugins.
[
{
"target": "neustadt",
"datapoints": [
[ 49.9897, "2021-05-26 02:36:17.300" ],
[ 49.9893, "2021-05-26 02:36:17.400" ],
[ 49.9888, "2021-05-26 02:36:17.500" ],
[ 49.9887, "2021-05-26 02:36:17.600" ]
]
},
{
"target": "dresden",
"datapoints": [
[ 49.9921, "2021-05-26 02:36:17.300" ],
[ 49.9918, "2021-05-26 02:36:17.400" ],
[ 49.9906, "2021-05-26 02:36:17.500" ],
[ 49.9906, "2021-05-26 02:36:17.600" ]
]
}
]
Example response to a limit violation:
{
"columns":["code","msg"],
"data":[
[429,"Limitation: minimum request interval"]
]
}
If you require downsampling of the desired time series to a lower resolution, or if it's necessary to perform transformations or selections of particular values within a successive time range, a corresponding function must be specified via the func
parameter.
By default, the first
selector function is used, which has no effect if the aggr
parameter is set to the maximum resolution of the requested time series.
It's always a good idea to specify func
and aggr
parameters because the aggregation interval defaults to 1 second if the aggr
parameter is not set and the maximum resolution of the specified time series may vary, (see the PREC [ms] column of the PMU tables).
curl 'https://api.gridradar.net/aggr_functions?token=your-token'
Selecting the first phase-angle measurement of every second using default aggregation settings:
{
"metric":"phase-angle",
"pmus": ...,
...
}
## e.g. returned timestamps of the selected values:
## 2021-05-26 02:36:01.0,
## 2021-05-26 02:36:02.0
Aggregating the 100ms frequency to it's one minute average:
{
"metric":"frequency"
"func":"mean",
"aggr":"1m"
"pmus": ...,
...
}
## e.g. returned timestamps of the result values:
## 2021-05-26 02:36:00.0,
## 2021-05-26 02:37:00.0
Calculating the difference of subsequent 10 seconds average frequency values:
NOTE: The difference
function always uses a nested mean
function, which has no effect if the aggr
parameter is set to the maximum resolution.
{
"metric":"frequency"
"func":"difference",
"aggr":"10s"
"pmus": ...,
...
}
## e.g. returned timestamps of the result values:
## 2021-05-26 02:36:00.0,
## 2021-05-26 02:36:10.0