oneapi
Sign in
Energie v1 / Piaţa de energie

Monthly market series

The market's monthly series in a single table: the average price, consumption, production by source and the exchange balance, month by month.

GET
https://oneapi.ro/api/energie/v1/piata/lunar

Query parameters

NameTypeDescriptionAccepted values
de_laoptional string | null Start of the range. Defaults to 7 days ago — for history, ask for it explicitly. e.g. 2015-01-01
pana_laoptional string | null End of the range. Defaults to now. e.g. 2026-09-01
zonaoptional string | null The EIC code of the bidding zone. Defaults to Romania. The only zone imported today is 10YRO-TEL------P; any other value returns 422, not an empty series. The list is in /piata/acoperire, under zone_ofertare. 10YRO-TEL------P

How it behaves

  • The history has a gap, and it is visible at /piata/acoperire. The series starts in 2015, but the historical import is still in progress: about 28-30 months are currently missing (2015-03 → 2017-08). A request falling inside the gap returns 200 with an empty list — which does NOT mean the market had no activity, but that the period has not been imported yet. The goluri field in the coverage route lists exactly which months are missing, computed from the data, so it shrinks on its own as the history fills in.
  • The series can extend past the present moment. Day-ahead prices are published in advance, so the last interval in the response is often an hour that has not been consumed yet. This is not an error and not a forecast of ours: it is the firm quotation, published by the exchange before delivery. The practical consequence: a window ending "now" can mix already-consumed hours with hours not yet delivered, and an average over it lumps them together. If you need strictly realised data, cut the window at the current hour.
  • The shape in which a long history is read. The same data at interval level means hundreds of thousands of rows; here a month is one row, and the averages stay weighted by interval duration.
  • ⚠️ Generation codes are NOT stable over time. The same coal plants appear under B05 in older series and under B02 in recent ones: the switchover happened in May-June 2015. In April 2015 B05 averaged 1,670 MW and B02 208; in May both move (1,024 / 573); from June the ratio is permanently inverted (157 / 1,434). Their sum is unchanged across the transition — 1,878, 1,597, 1,591 MW — so the plants did not move, the code they are reported under did. A series built on a single code breaks there; use pe_grupa, which is stable.
  • Read ore_acoperite, separately for price and load. They are not covered equally: some months have the price published in full while load is only partial. An incomplete month still yields an average that looks just as credible at first glance.
  • The month is bounded in UTC, like the rest of the series.

What it is for

  • See how the electricity price moved across whole years, in a single request.
  • Settle a PZU-indexed contract: the weighted monthly average is the reference actually used.
  • Track how the country generation mix shifted — solar arriving, coal leaving.

Response structure

All fields below live inside data.

FieldTypeDescription
luni[].luna string Luna, AAAA-LL.
luni[].pret.medie_ponderata_eur_mwh number Media lunară ponderată.
luni[].productie.pe_grupa object Grupă → MWh. Forma stabilă în timp.
luni[].schimburi.sold_mwh number Import − export, în MWh.
inregistrari integer How many months are in the response.
luni[].pret.minim number The lowest price of the month.
luni[].pret.maxim number The highest price of the month.
luni[].pret.intervale integer How many price intervals were published.
luni[].pret.intervale_cu_pret_negativ integer How many intervals were priced below zero.
luni[].pret.ore_acoperite integer How many market hours the month covers. A full month has 672-744.
luni[].consum.putere_medie_mw number Average load for the month, weighted by duration.
luni[].consum.varf_mw integer The load peak of the month.
luni[].consum.energie_mwh number Energy consumed, derived from power × duration.
luni[].consum.ore_acoperite integer How many load hours are published — can be less than for price.
luni[].productie.energie_totala_mwh integer Energy generated in the month, all sources.
luni[].productie.energie_regenerabila_mwh integer Energy from sources confirmed as renewable.
luni[].productie.regenerabil_procent null The renewable share for that month.
luni[].productie.pe_cod array Energy per ENTSO-E code. ⚠️ The codes are NOT stable over time.
luni[].schimburi.import_mwh integer Energy in through the borders during the month.
luni[].schimburi.export_mwh integer Energy out through the borders.
luni[].coduri_neconfirmate array Codes with output that month which have no confirmed label.
observatie string Why the averages are weighted, and what an incomplete month means.
avertisment_coduri string The warning about generation codes being reclassified over time.
sursa object ENTSO-E Transparency Platform, with the required attribution.

Response examples

GEThttps://oneapi.ro/api/energie/v1/piata/lunar?de_la=2015-01-01
{
    "data": {
        "zona": "10YRO-TEL------P",
        "de_la": "2014-12-31 22: 00: 00",
        "pana_la": "2026-10-06 20: 39: 50",
        "inregistrari": 143,
        "luni": [
            {
                "luna": "2014-12",
                "pret": {
                    "medie_ponderata_eur_mwh": 202.08,
                    "minim": 202.08,
                    "maxim": 202.08,
                    "intervale": 1,
                    "intervale_cu_pret_negativ": 0,
                    "ore_acoperite": 1
                },
                "consum": null,
                "productie": {
                    "energie_totala_mwh": 0,
                    "energie_regenerabila_mwh": 0,
                    "regenerabil_procent": null,
                    "pe_cod": [],
                    "pe_grupa": []
                },
                "schimburi": {
                    "import_mwh": 0,
                    "export_mwh": 0,
                    "sold_mwh": 0
                },
                "coduri_neconfirmate": []
            }
        ],
        "observatie": "Mediile lunare sunt PONDERATE cu durata intervalului, nu aritmetice — o lună poate amesteca intervale de 15 minute cu unele orare. `ore_acoperite` spune cât din lună e efectiv publicat: o lună incompletă dă tot o medie, care arată la fel de credibilă ca oricare alta.",
        "avertisment_coduri": "Codurile de producţie NU sunt stabile în timp: aceleaşi centrale pe cărbune au fost raportate sub `B05` până în trecut şi sub `B02` acum. O serie pe un singur cod se rupe la reclasificare — foloseşte `grupa` sau suma codurilor de cărbune. Vezi /energie/v1/piata/surse.",
        "sursa": {
            "nume": "ENTSO-E Transparency Platform",
            "url": "https://transparency.entsoe.eu",
            "atribuire": "Date din ENTSO-E Transparency Platform.",
            "licenta": "Reutilizare permisă cu ATRIBUIRE obligatorie către Transparency Platform. Drepturile nu sunt sublicențiabile.",
            "observatie": "Zona `piata` e seria oficială europeană; zona `sen` e instantaneul Transelectrica. Au surse, pași și definiții diferite — cifrele lor nu se compară direct."
        }
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422validareThe range is reversed.
429cota_depasitaThe plan's monthly quota has been exceeded (see Retry-After).

All errors share the same shape. eroare.cod is stable and is the value you should branch on in code — not the text in mesaj, which may change.

{
    "eroare": {
        "cod": "validare",
        "mesaj": "The range is reversed.",
        "detalii": {
            "de_la": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}