> ## Documentation Index
> Fetch the complete documentation index at: https://docs.powersignals.co.za/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Provenance

> Where our data comes from and how we handle it.

# Data Provenance

Power Signals is a **primary-source data provider**. We collect, parse, and serve data directly from official sources — no third-party aggregators in the chain.

## Sources

| Dataset           | Source                          | Update Frequency |
| ----------------- | ------------------------------- | ---------------- |
| Grid System State | Eskom Data Portal               | Hourly           |
| Grid Stress Index | Computed from Grid System State | Hourly           |

## Timezone Handling

All timestamps in API responses are in **UTC**.

The original source data from Eskom uses South African Standard Time (SAST, UTC+2). We convert all timestamps to UTC during ingestion to provide a consistent, unambiguous time reference.

```json theme={null}
{
  "meta": {
    "timezone": "UTC"
  },
  "data": [
    {
      "ts": "2026-01-01T00:00:00Z"
    }
  ]
}
```

<Tip>
  If you need SAST timestamps for display, add 2 hours to any UTC timestamp in the response.
</Tip>

## Data Pipeline

```
Source (Eskom)
  → Collection (seconds after publication)
  → Parsing & Validation
  → UTC Conversion
  → Storage
  → API Response
```

Data is typically available within **seconds** of publication by the upstream source.

## Derived Data

Some fields are computed from raw data rather than sourced directly:

| Field                 | Derivation                                       |
| --------------------- | ------------------------------------------------ |
| `renewable_share_pct` | `(total_re_mw / total_generation_mw) × 100`      |
| `net_import_mw`       | `imports_mw - exports_mw`                        |
| `forecast_error_mw`   | `residual_demand_mw - residual_forecast_mw`      |
| `ocgt_ramp_mw`        | Hour-over-hour change in OCGT output             |
| Grid Stress Index     | Multi-factor composite from system state signals |

The `meta.derived` field in responses indicates whether data includes derived calculations:

```json theme={null}
{
  "meta": {
    "derived": true,
    "derivation_method": "aggregation_from_1h"
  }
}
```

## Daily Aggregation

When using `interval=1d`, daily values are aggregated from hourly data:

* **MW columns** — averaged over the day
* **Renewable share** — `sum(total_re) / sum(total_generation) × 100`
* **OCGT ramp** — `max` (up) and `min` (down) of hourly ramps
* **Day boundary** — UTC midnight to midnight

## Data Completeness

We monitor all upstream feeds continuously. If data is missing or delayed:

* The API returns an empty `data` array for the affected period
* The `meta` object may include a `data_delay` flag
* Historical backfills are applied automatically when delayed data arrives
