Dokumentace API

Spotovky.cz poskytuje spotové ceny elektřiny z OTE-CR přes REST API a MQTT broker. Vše je zdarma, bez registrace, bez API klíče.

Rychlý start

Nejrychlejší způsob jak získat data — stačí jedna HTTP žádost nebo MQTT subscribe.

REST API

cURL
curl https://api.spotovky.cz/v1/today

MQTT

mosquitto_sub
mosquitto_sub -h spotovky.cz -t "v1/current/json"

Díky retain zprávám na MQTT dostanete data okamžitě po přihlášení — nemusíte čekat na další aktualizaci.

REST API

Base URL: https://api.spotovky.cz

Odpovědi jsou vždy ve formátu JSON s hlavičkou Content-Type: application/json. Cache je řízena hlavičkou Cache-Control: public, max-age=N kde N je počet sekund do konce aktuální 15minutové periody.

Endpointy

GET /v1/today

Vrátí data pro dnešní datum (Europe/Prague)

GET /v1/tomorrow

Vrátí data pro zítřejší datum. Dostupné obvykle od 15:00 po publikaci z OTE-CR.

⚠ Pokud data pro zítřek nejsou k dispozici, vrátí dnešní data.

GET /v1/yesterday

Vrátí data pro včerejší datum.

GET /v1/{datum}

Vrátí data pro konkrétní datum ve formátu YYYY-MM-DD, např. /v1/2026-03-13.

• Datum v budoucnu (dále než zítřek) → vrátí zítřejší data
• Neplatný formát data → HTTP 400
• Data pro datum nejsou dostupná → vrátí dnešní data

ℹ️

Historická data jsou dostupná od spuštění služby. Starší záznamy mohou chybět.

Formát odpovědi

Každá odpověď obsahuje datum, kurz EUR/CZK a pole slots s 15minutovými intervaly.

Příklad odpovědi — /v1/today
{
  "date": "2026-03-13",       // datum (Europe/Prague)
  "rate": 24.43,              // kurz EUR/CZK z ČNB
  "slots": [
    {
      "t":    "00:00",           // začátek intervalu
      "czk":  2.60,             // cena v Kč/kWh (zaokrouhleno na 2 des. místa)
      "rank": 55               // pořadí od nejlevnější (1 = nejlevnější)
    },
    {
      "t":    "00:15",
      "czk":  2.31,
      "rank": 52
    },
    // ... celkem 92, 96 nebo 100 slotů (viz sekce Letní/zimní čas)
  ]
}
Pole Typ Popis
datestringDatum ve formátu YYYY-MM-DD
ratenumberKurz EUR/CZK z ČNB platný pro daný den
slotsarrayPole 15minutových intervalů, seřazené chronologicky
slots[].tstringZačátek intervalu ve formátu HH:MM
slots[].czknumberSpotová cena v Kč/kWh, zaokrouhlena na 2 desetinná místa. Může být záporná.
slots[].rankintegerPořadí intervalu v rámci dne od nejlevnějšího (1 = nejlevnější)
⚠️

Záporné ceny — při přebytku solární nebo větrné energie mohou být spotové ceny záporné. Pole czk může obsahovat zápornou hodnotu, počítejte s tím ve svém kódu.

HTTP status kódy

KódPopis
200 OKÚspěch. Odpověď obsahuje data.
400 Bad RequestNeplatný formát data v URL (např. /v1/abc). Odpověď: {"error": "Invalid date format..."}
503 Service UnavailableData nejsou dostupná ani pro dnešek (výpadek fetcheru). Odpověď: {"error": "No data available"}

MQTT

Broker je dostupný na adrese spotovky.cz, port 1883. Připojení nevyžaduje uživatelské jméno ani heslo.

Připojení
# mosquitto_sub
mosquitto_sub -h spotovky.cz -p 1883 -t "v1/today/json"

# Python (paho-mqtt)
import paho.mqtt.client as mqtt
client = mqtt.Client()
client.connect("spotovky.cz", 1883)
client.subscribe("v1/current/json")

Topicy

TopicFormátPopis
v1/today/jsonJSONDnešní ceny — všechny sloty. Retain, QoS 1.
v1/today/binBinárníDnešní ceny — kompaktní binární formát. Retain, QoS 1.
v1/tomorrow/jsonJSONZítřejší ceny — dostupné od ~15:00. Retain, QoS 1. Po půlnoci smazáno.
v1/tomorrow/binBinárníZítřejší ceny — binární formát. Retain, QoS 1. Po půlnoci smazáno.
v1/current/jsonJSONAktuální 15minutový interval. Retain, QoS 1. Aktualizuje se každých 15 minut.
v1/current/binBinárníAktuální interval — binární formát. Retain, QoS 1.

Formát zpráv today/json a tomorrow/json je shodný s odpovědí REST API. Zpráva current/json obsahuje pouze aktuální interval:

v1/current/json
{
  "t":    "14:15",   // začátek intervalu
  "czk":  1.82,     // cena v Kč/kWh
  "rank": 12        // pořadí v rámci dnešního dne
}

Pravidla přístupu

🚫

Publish je zakázán. Broker přijímá pouze subscribe. Pokus o publish na jakýkoliv topic bude tiše odmítnut — zpráva nebude doručena a připojení zůstane aktivní.

⚠️

Povolené topicy. Subscribe je možný pouze na topicy uvedené v tabulce výše. Subscribe na jiný topic bude odmítnut.

ℹ️

Wildcard subscribe (#, +) není povolen. Vždy se přihlašujte na konkrétní topic.

Opakované pokusy o zakázané operace mohou vést k dočasnému zablokování IP adresy.

Harmonogram aktualizací

ČasAkceOvlivněné topicy
00:00Publikace dnešních cen, smazání zítřejších retain zprávtoday/json, today/bin, tomorrow/json*, tomorrow/bin*
*/15 * * *Aktualizace aktuálního intervalucurrent/json, current/bin
14:55Stažení dat z OTE-CR a ČNB
15:00Publikace dnešních a zítřejších centoday/json, today/bin, tomorrow/json, tomorrow/bin

* Smazání retain zprávy = publish prázdné zprávy na daný topic s retain=true, standardní MQTT mechanismus.

Datové formáty

JSON formát

Podrobný popis viz sekce Formát odpovědi REST API. Zprávy na MQTT topicech today/json a tomorrow/json mají identickou strukturu.

Binární formát

Kompaktní formát pro embedded zařízení. Všechny hodnoty jsou little-endian.

today/bin a tomorrow/bin

OffsetVelikostTypObsah
08 Buint64Unix timestamp půlnoci daného dne (Europe/Prague)
82 Buint16Kurz EUR/CZK × 100 (např. 2443 = 24.43 Kč/EUR)
101 Buint8Počet period N (92, 96 nebo 100 — viz letní/zimní čas)
11N × 2 BN × uint16Ceny v haléřích (czk/kWh × 100), záporné ceny jsou oříznuty na 0
11 + N×2N × 1 BN × uint8Pořadí intervalu (1 = nejlevnější, N = nejdražší)

Celková délka: 11 + N×3 bytů (283 B pro 92 period / 299 B pro 96 / 311 B pro 100).

Index slotu odpovídá pořadí od půlnoci: slot 0 = 00:00, slot 1 = 00:15, atd. Čas slotu: midnight_unix + index × 900.

current/bin

OffsetVelikostTypObsah
08 Buint64Unix timestamp začátku aktuálního intervalu (UTC)
82 Buint16Cena v haléřích (czk/kWh × 100), min. 0
101 Buint8Pořadí intervalu v rámci dne (1 = nejlevnější)
112 Buint16Kurz EUR/CZK × 100

Celková délka: vždy 13 bytů.

Dekódování v C (ESP32 / Arduino)
// current/bin — 13 bytů
uint64_t timestamp;
uint16_t halere, rate_x100;
uint8_t  rank;

memcpy(&timestamp,  data + 0,  8);
memcpy(&halere,     data + 8,  2);
rank = data[10];
memcpy(&rate_x100,  data + 11, 2);

float czk     = halere    / 100.0f;
float eur_czk = rate_x100 / 100.0f;

Serial.printf("%.2f Kč/kWh, rank %d, kurz %.2f\n", czk, rank, eur_czk);
Dekódování today/bin v Pythonu
import struct, datetime, zoneinfo

def decode_day_bin(data: bytes):
    midnight, rate_x100, n = struct.unpack_from("<QHB", data, 0)
    prices = struct.unpack_from(f"<{n}H", data, 11)
    ranks  = struct.unpack_from(f"<{n}B", data, 11 + n * 2)

    eur_czk = rate_x100 / 100
    tz = zoneinfo.ZoneInfo("Europe/Prague")

    for i, (halere, rank) in enumerate(zip(prices, ranks)):
        slot_ts = midnight + i * 900
        dt = datetime.datetime.fromtimestamp(slot_ts, tz)
        czk = halere / 100
        print(f"{dt:%H:%M}  {czk:.2f} Kč/kWh  rank {rank}/{n}")

Letní a zimní čas (DST)

Počet slotů za den není vždy 96. OTE-CR publikuje skutečný počet 15minutových intervalů:

SituacePočet slotůVelikost today/bin
Přechod na letní čas (poslední neděle v březnu)92287 B
Běžný den96299 B
Přechod na zimní čas (poslední neděle v říjnu)100311 B

Pole slots v JSON vždy obsahuje správný počet záznamů. V binárním formátu je počet period uložen v bytu na offsetu 10 — vždy čtěte tento byte před parsováním dat.

⚠️

Nepředpokládejte pevný počet 96 slotů. Vždy použijte hodnotu N z binárního payloadu nebo délku pole slots z JSON.

Limity a podmínky

Dostupnost

Služba je provozována jako hobby projekt bez záruky dostupnosti. Nejsou poskytovány žádné SLA. Data mohou chybět v případě nedostupnosti OTE-CR API nebo výpadku serveru.

Zdroje dat

Spotové ceny pocházejí z OTE-CR (Operátor trhu s elektřinou). Kurz EUR/CZK pochází z ČNB (Česká národní banka) a je aktualizován jednou denně po 14:30. Pro víkendy a svátky se používá poslední dostupný kurz.

⚠️

Ceny jsou pouze spotové — neobsahují distribuci, daně ani poplatky. Nejsou vhodné jako podklad pro fakturaci bez dalšího zpracování.

Použití

Data jsou veřejná a jejich použití není omezeno. Pokud službu využíváte ve svém projektu, oceníme zmínku o zdrojích dat (OTE-CR, spotovky.cz).

Kontakt

Dotazy, hlášení chyb nebo návrhy pište na martin@lysek.cz.