Get grid stress index
curl --request GET \
--url https://api.powersignals.co.za/api/v1/features/grid-stress \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.powersignals.co.za/api/v1/features/grid-stress"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.powersignals.co.za/api/v1/features/grid-stress', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.powersignals.co.za/api/v1/features/grid-stress",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.powersignals.co.za/api/v1/features/grid-stress"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.powersignals.co.za/api/v1/features/grid-stress")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.powersignals.co.za/api/v1/features/grid-stress")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"meta": {
"start": "<string>",
"end": "<string>",
"dataset": "features.grid_stress_index",
"feature": "grid_stress_index",
"version": "v1",
"interval": "1h",
"timezone": "UTC",
"schema_version": "1.0",
"derived": true,
"derivation_method": "computed_from_grid.system_state"
},
"data": [
{}
]
}{
"error": "<string>",
"detail": "<string>"
}Features
Grid Stress Index
Returns the Grid Stress Index for the given time range. This is a derived signal computed from grid system state data, indicating overall grid stress level. Only 1h interval is supported.
GET
/
api
/
v1
/
features
/
grid-stress
Get grid stress index
curl --request GET \
--url https://api.powersignals.co.za/api/v1/features/grid-stress \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.powersignals.co.za/api/v1/features/grid-stress"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.powersignals.co.za/api/v1/features/grid-stress', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.powersignals.co.za/api/v1/features/grid-stress",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.powersignals.co.za/api/v1/features/grid-stress"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.powersignals.co.za/api/v1/features/grid-stress")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.powersignals.co.za/api/v1/features/grid-stress")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"meta": {
"start": "<string>",
"end": "<string>",
"dataset": "features.grid_stress_index",
"feature": "grid_stress_index",
"version": "v1",
"interval": "1h",
"timezone": "UTC",
"schema_version": "1.0",
"derived": true,
"derivation_method": "computed_from_grid.system_state"
},
"data": [
{}
]
}{
"error": "<string>",
"detail": "<string>"
}Overview
The Grid Stress Index is a derived signal that indicates the overall stress level of the South African power grid at any given hour. It is computed from multiple system state factors including residual demand, OCGT ramp rates, renewable penetration, and reserve margins.Interpretation
| Value Range | Meaning |
|---|---|
| 0.0 – 0.3 | Low stress — grid operating comfortably |
| 0.3 – 0.6 | Moderate stress — elevated demand or reduced reserves |
| 0.6 – 0.8 | High stress — potential for loadshedding |
| 0.8 – 1.0 | Critical — loadshedding likely or active |
Components
Each data point includes acomponents object breaking down the factors contributing to the stress score:
{
"ts": "2026-01-01T18:00:00Z",
"value": 0.72,
"components": {
"residual_demand": 0.8,
"ocgt_ramp": 0.6,
"reserve_margin": 0.75,
"renewable_shortfall": 0.65
},
"version": "v1"
}
Use Cases
- Trigger alerts when grid stress exceeds a threshold
- Correlate grid stress with market prices
- Power demand-response automation
- Feed into energy trading models
Authorizations
API key obtained from the Power Signals dashboard.
Query Parameters
Include the components breakdown for each stress score. Defaults to false.
End datetime in ISO-8601 format.
Data resolution. Only 1h is currently supported.
Available options:
1h Start datetime in ISO-8601 format.

