← Portal

API Dokumentacija

KOSAVA v7 OpenData

Agencija za zaštitu životne sredine SEPA — API Documentation

Portal omogućava pristup podacima o kvalitetu vazduha i meteorološkim parametrima iz mreža za praćenje. API je dostupan isključivo za čitanje: nema upisa podataka, nema autentikacije i nema ograničenja broja zahteva. Svi prikazani podaci pripadaju organizaciji naznačenoj na samom portalu.

v1.2.0 Samo za čitanje Bez autentikacije

Autentikacija

Ovaj API ne zahteva autentikaciju. Svi endpointi su javno dostupni. Nema API ključeva, tokena niti sesijskih kolačića. Jednostavno šaljite HTTP GET zahteve na bilo koji endpoint naveden ispod.

Metod autentikacije

Nema

Kredencijali nisu potrebni ni za jedan endpoint. Portal je dizajniran kao otvoreni podatkovni resurs za javnu upotrebu.

Konfiguracija servera

KEY_PREFIX & EXPECTED_SCHEMA_VERSION

Ovo su serverske promenljive okruženja koje operator postavlja pri postavljanju. One vezuju portal za imenski prostor podataka jedne organizacije i primenjuju kompatibilnost snimka — nisu API parametri.

Base URL i format odgovora

Osnovna URL adresa zavisi od okruženja. Sve putanje u ovoj dokumentaciji su relativne u odnosu na koren portala. Za lokalnu razvojnu instancu osnovna URL adresa je obično http://localhost:8000.

Format odgovora

JSON (application/json)

Svi endpointi podataka vraćaju Content-Type: application/json. Endpoint za izvoz (/portal/export) vraća binarno preuzimanje datoteke. HTML rute portala vraćaju text/html.

Prozori merenja

1h · 1d · 7d · 14d · 30d

Snimak sadrži unapred agregisane podatke za pet vremenskih prozora. Nisu svi prozori prisutni u svakom snimku — proverite polje supported_windows na GET /meta.

Kodovi grešaka

Sve greške se vraćaju kao JSON sa poljem koje opisuje problem. Health endpointi vraćaju polja umesto toga.

200 OK

Uspeh

Zahtev je uspešan. Telo odgovora sadrži tražene podatke.

400 Bad Request

Neispravni parametri

Jedan ili više obaveznih parametara upita nedostaje, prazan je, nije validan ceo broj (za ID-eve), ili ima nepodržanu vrednost (za window ili format).

404 Not Found

Resurs nije pronađen

Organizacija, stanica, komponenta ili traženi podaci merenja ne postoje u aktivnom snimku ili nemaju javno dostupnih podataka.

503 Service Unavailable

Servis nedostupan

Redis je nedostupan, pokazivač aktivnog snimka nedostaje, ili verzija šeme snimka ne odgovara EXPECTED_SCHEMA_VERSION. Portal nije spreman za posluživanje podataka.

Health

Lagane probe za orkestratore kontejnera i balansere opterećenja. Nijedan endpoint ne zahteva autentikaciju niti pristupa podacima merenja.

GET /health/live Provjera živosti procesa

Potvrđuje da je proces živ i da HTTP server prihvata veze. Ovaj endpoint ne izvodi nikakav I/O i uvek vraća 200 OK dok god proces radi. Koristite kao probu živosti kontejnera.

Odgovori

StatusOpisPrimer tela
200 Proces je živ {"status":"ok","check":"live"}

Primeri koda

curl -s http://opendata.kosava.cloud/health/live
import requests

resp = requests.get("http://opendata.kosava.cloud/health/live")
print(resp.json())
# {"status": "ok", "check": "live"}
const resp = await fetch("http://opendata.kosava.cloud/health/live");
const data = await resp.json();
console.log(data);
// { status: "ok", check: "live" }
GET /health/ready Provjera spremnosti snimka

Proverava da li je Redis konekcija ispravna i da li verzija aktivnog snimka odgovara EXPECTED_SCHEMA_VERSION. Vraća 200 sa snapshot_id kada je spreman. Vraća 503 kada Redis nije dostupan, pokazivač snimka nedostaje ili verzija šeme nije kompatibilna. Koristite kao probu spremnosti kontejnera i zdravstvenu kapiju balansera opterećenja.

Odgovori

StatusOpisPrimer tela
200 Redis dostupan, snimak kompatibilan {"status":"ok","check":"ready","snapshot_id":"snap_20240101_120000"}
503 Redis nedostupan ili nekompatibilna šema {"status":"error","check":"ready","detail":"..."}

Primeri koda

curl -s http://opendata.kosava.cloud/health/ready
import requests

resp = requests.get("http://opendata.kosava.cloud/health/ready")
if resp.status_code == 200:
    print("Ready:", resp.json()["snapshot_id"])
else:
    print("Not ready:", resp.json()["detail"])
const resp = await fetch("http://opendata.kosava.cloud/health/ready");
const data = await resp.json();
if (resp.ok) console.log("Snapshot:", data.snapshot_id);
else console.error("Not ready:", data.detail);

Metapodaci

Endpointi za otkrivanje strukture skupa podataka: organizacije, mreže za praćenje, stanice i komponente merenja. Počnite ovde da saznate koje ID-eve koristiti u upitima merenja. Svi metapodaci dolaze iz aktivnog Redis snimka i samo su za čitanje.

GET /meta Manifest snimka

Vraća manifest trenutno aktivnog Redis snimka: vremensku oznaku generisanja, podržane prozore merenja i agregatne brojeve za organizacije, mreže, stanice, komponente i redove merenja. Koristite supported_windows da saznate koje vrednosti prozora su važeće za upite merenja.

Odgovori

StatusOpis
200 Objekat manifesta aktivnog snimka
503 Snimak nedostupan ili nekompatibilan

Primeri koda

curl -s http://opendata.kosava.cloud/meta | python3 -m json.tool
import requests

meta = requests.get("http://opendata.kosava.cloud/meta").json()
print("Snapshot:", meta["generated_at"])
print("Windows:", meta["supported_windows"])
print("Stations:", meta["counts"]["stations"])
const meta = await fetch("/meta").then(r => r.json());
console.log(meta.supported_windows); // ["1h","1d","7d","14d","30d"]
console.log(meta.counts.stations);   // 12
GET /organizations Lista svih organizacija

Vraća sve organizacije u aktivnom snimku. Pošto je jedna instanca portala vezana za jednu organizaciju putem KEY_PREFIX, ova lista obično sadrži tačno jedan unos. Svaki objekat uključuje organization_id, name i short_name.

Odgovori

StatusOpis
200Niz objekata organizacija
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/organizations
orgs = requests.get("http://opendata.kosava.cloud/organizations").json()
org_id = orgs[0]["organization_id"]  # typically 1 org
const orgs = await fetch("/organizations").then(r => r.json());
const orgId = orgs[0].organization_id;
GET /networks Lista svih mreža

Vraća sve mreže za praćenje definisane u aktivnom snimku. Mreže grupišu stanice unutar imenovanog programa merenja ili geografskog područja. Svaki objekat uključuje network_id, network_code, name i short_name.

Odgovori

StatusOpis
200Niz objekata mreža
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/networks
networks = requests.get("http://opendata.kosava.cloud/networks").json()
for n in networks:
    print(n["network_code"], "-", n["name"])
const networks = await fetch("/networks").then(r => r.json());
networks.forEach(n => console.log(n.network_code, n.name));
GET /stations Lista svih stanica

Vraća sve javne stanice za praćenje u svim organizacijama i mrežama u aktivnom snimku. Svaki objekat uključuje station_id, station_name, station_code, organization_id, network_id, network_code i geografska polja kao što su city i municipality gde su dostupna. Za filtriranje po organizaciji koristite GET /{organization_id}/stations.

Odgovori

StatusOpis
200Niz objekata stanica
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/stations
stations = requests.get("http://opendata.kosava.cloud/stations").json()
for s in stations:
    print(s["station_id"], s["station_name"], s["city"])
const stations = await fetch("/stations").then(r => r.json());
console.log(`${stations.length} stations found`);
GET /components Lista svih komponenti merenja

Vraća sve komponente merenja (zagađivači i meteorološki parametri) definisane u aktivnom snimku. Svaki objekat uključuje component_id, short_name i unit. Ovde se pojavljuju samo javno vidljive komponente. Meteorološki parametri uključuju brzinu vetra, temperaturu, vlažnost i padavine; parametri zagađenja uključuju čestice (PM10, PM2.5) i gasovite zagađivače.

Odgovori

StatusOpis
200Niz objekata komponenti
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/components
components = requests.get("http://opendata.kosava.cloud/components").json()
pm10 = next(c for c in components if c["short_name"] == "PM10")
print(pm10["component_id"], pm10["unit"])  # 1001 ug/m3
const components = await fetch("/components").then(r => r.json());
const pm10 = components.find(c => c.short_name === "PM10");
console.log(pm10.component_id, pm10.unit);
GET /{"{organization_id}"}/stations Lista stanica organizacije

Vraća sve javne stanice za praćenje za određenu organizaciju. Oblik odgovora je identičan GET /stations, ali filtriran po datom organization_id. Vraća 404 ako organizacija ne postoji ili nema javnih stanica u aktivnom snimku.

Parametri putanje

NazivTipObaveznoOpis
organization_id integer da ID organizacije. Dobiti sa GET /organizations.

Odgovori

StatusOpis
200Niz objekata stanica za organizaciju
404Organizacija nije pronađena ili nema javnih stanica
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/1/stations
org_id = 1
stations = requests.get(
    f"http://opendata.kosava.cloud/{org_id}/stations"
).json()
print(f"{len(stations)} stations in org {org_id}")
const orgId = 1;
const stations = await fetch(`/${orgId}/stations`).then(r => r.json());
console.log(`${stations.length} stations`);
GET /{"{organization_id}"}/stations/{"{station_id}"}/meta Metapodaci stanice i javne komponente

Vraća detaljne metapodatke za jednu stanicu, uključujući listu javnih komponenti merenja (public_components) dostupnih za tu stanicu. Svaki unos komponente uključuje component_id, short_name i unit. Ovo je polazna tačka za otkrivanje koje komponente mogu biti upitane putem endpointa merenja. Vraća 404 ako organizacija ili stanica ne postoje u aktivnom snimku.

Parametri putanje

NazivTipObaveznoOpis
organization_id integer da ID organizacije. Dobiti sa GET /organizations.
station_id integer da ID stanice. Dobiti sa GET /stations.

Odgovori

StatusOpis
200Objekat metapodataka stanice sa ugrađenim nizom public_components
404Organizacija ili stanica nisu pronađene
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/1/stations/101/meta
meta = requests.get(
    "http://opendata.kosava.cloud/1/stations/101/meta"
).json()
for comp in meta["public_components"]:
    print(comp["component_id"], comp["short_name"], comp["unit"])
const meta = await fetch("/1/stations/101/meta").then(r => r.json());
meta.public_components.forEach(c =>
  console.log(c.component_id, c.short_name, c.unit)
);

Merenja

Endpointi za preuzimanje vremenskih serija podataka o merenjima životne sredine. Sve vrednosti su unapred izračunate u aktivnom Redis snimku — nema agregacije u realnom vremenu. Koristite endpointe metapodataka da biste najpre pronašli važeće ID-eve organizacije, stanice i komponente.

GET /measurements Vremenska serija za komponentu stanice

Vraća normalizovane podatke vremenskih serija za jednu komponentu na jednoj stanici tokom traženog vremenskog prozora. Sva četiri parametra upita su obavezna. Odgovor uključuje naziv stanice, detalje komponente, korišćeni prozor i niz points sortiran uzlazno po datumu i vremenu. Svaka tačka ima date (GGGG-MM-DD), time (HH:MM) i numeričku vrednost value. Parametar window mora biti jedan od: 1h, 1d, 7d, 14d, 30d — i mora biti prisutan u supported_windows snimka.

Parametri upita

NazivTipObaveznoOpisPrimer
organization_id integer da ID organizacije 1
station_id integer da ID stanice 101
component_id integer da ID komponente 1001
window string da Vremenski prozor. Jedan od: 1h 1d 7d 14d 30d 1d

Odgovori

StatusOpis
200Normalizovano telo vremenskih serija sa nizom points
400Nedostaje, prazan ili neispravan parametar; nepodržana vrednost prozora
404Stanica ili komponenta nije pronađena, ili nema podataka za prozor
503Snimak nedostupan

Primeri koda

curl -s \
  "http://opendata.kosava.cloud/measurements?organization_id=1&station_id=101&component_id=1001&window=1d"
import requests

resp = requests.get(
    "http://opendata.kosava.cloud/measurements",
    params={
        "organization_id": 1,
        "station_id": 101,
        "component_id": 1001,
        "window": "1d",
    },
)
resp.raise_for_status()
data = resp.json()
print(f"{data['station_name']} — {data['component_short_name']} ({data['unit']})")
for pt in data["points"]:
    print(pt["date"], pt["time"], pt["value"])
const params = new URLSearchParams({
  organization_id: "1",
  station_id: "101",
  component_id: "1001",
  window: "1d",
});
const resp = await fetch(`/measurements?${params}`);
if (!resp.ok) throw new Error(await resp.text());
const data = await resp.json();
console.log(`${data.station_name} — ${data.component_short_name} (${data.unit})`);
data.points.forEach(pt => console.log(pt.date, pt.time, pt.value));
GET /{"{organization_id}"}/stations/{"{station_id}"}/measurements/last_hour Merenja iz poslednjeg sata

Vraća sva merenja komponenti zabeležena u poslednjem satu za određenu stanicu. Telo odgovora sadrži niz hours gde svaki unos ima date (ISO-8601 string datuma), time (HH:MM) i listu components. Svaki unos komponente uključuje component_id i numeričku vrednost value. Vraća 404 ako stanica ne postoji ili nema podataka za poslednji sat.

Parametri putanje

NazivTipObaveznoOpis
organization_id integer da ID organizacije
station_id integer da ID stanice

Odgovori

StatusOpis
200Telo za poslednji sat sa nizom hours, svaki sadrži listu components
404Stanica nije pronađena ili nema podataka za poslednji sat
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/1/stations/101/measurements/last_hour
data = requests.get(
    "http://opendata.kosava.cloud/1/stations/101/measurements/last_hour"
).json()
for hour in data["hours"]:
    print(hour["date"], hour["time"])
    for comp in hour["components"]:
        print("  component", comp["component_id"], "=", comp["value"])
const data = await fetch("/1/stations/101/measurements/last_hour")
  .then(r => r.json());
data.hours.forEach(hour => {
  console.log(hour.date, hour.time);
  hour.components.forEach(c => console.log(" component", c.component_id, "=", c.value));
});
GET /{"{organization_id}"}/stations/{"{station_id}"}/measurements/last_24h Merenja poslednjih 24 sata

Vraća sva merenja komponenti zabeležena tokom poslednjih 24 sata za određenu stanicu. Struktura tela identična je last_hour: niz hours gde svaki unos ima date, time i components. Sve javno izložene komponente stanice su uključene u svaki satni unos gde postoje podaci. Vraća 404 ako stanica ne postoji ili nema podataka za poslednjih 24 sata.

Parametri putanje

NazivTipObaveznoOpis
organization_id integer da ID organizacije
station_id integer da ID stanice

Odgovori

StatusOpis
200Telo za poslednjih 24 sata sa nizom hours do 24 satna unosa
404Stanica nije pronađena ili nema podataka za poslednjih 24 sata
503Snimak nedostupan

Primeri koda

curl -s http://opendata.kosava.cloud/1/stations/101/measurements/last_24h
data = requests.get(
    "http://opendata.kosava.cloud/1/stations/101/measurements/last_24h"
).json()
print(f"{len(data['hours'])} hours of data")
const data = await fetch("/1/stations/101/measurements/last_24h")
  .then(r => r.json());
console.log(`${data.hours.length} hours of data`);

Izvoz

Preuzmite vremenske serije merenja kao strukturisanu datoteku. Podržani formati su CSV (UTF-8), XLSX (Excel) i ODS (LibreOffice Calc). Izvezena datoteka sadrži sve kontekstualne kolone — organizacija, mreža, stanica, komponenta, datum, vreme, jedinica i numerička vrednost.

GET /portal/export Preuzmi podatke merenja kao datoteku

Gradi i strujno prenosi datoteku tabele za preuzimanje koja sadrži podatke vremenskih serija merenja za jednu komponentu na jednoj stanici. Svih pet parametara upita je obavezno. Prozor 1h nije podržan za izvoz. Izvezena datoteka sadrži jedan red po tački merenja sa kolonama: organization_id, organization_name, station_id, station_name, station_code, network_id, network_code, date, time, component_id, component_short_name, unit, value. Numeričke vrednosti su formatirane na dve decimale.

Parametri upita

NazivTipObaveznoOpisPrimer
organization_id integer da ID organizacije 1
station_id integer da ID stanice 101
component_id integer da ID komponente 1001
window string da Vremenski prozor. Jedan od: 1d 7d 14d 30d (1h nije podržan) 7d
format string da Format datoteke. Jedan od: csv xlsx ods csv

Odgovori

StatusContent-TypeOpis
200 text/csv / application/vnd.openxmlformats-officedocument.spreadsheetml.sheet / application/vnd.oasis.opendocument.spreadsheet Preuzimanje datoteke sa Content-Disposition: attachment
400application/jsonNedostaje/neispravan parametar ili nepodržan prozor/format
404application/jsonStanica ili komponenta nije pronađena, ili nema podataka za prozor
503application/jsonSnimak nedostupan

Primeri koda

# Download as CSV
curl -OJ \
  "http://opendata.kosava.cloud/portal/export?organization_id=1&station_id=101&component_id=1001&window=7d&format=csv"

# Download as XLSX
curl -OJ \
  "http://opendata.kosava.cloud/portal/export?organization_id=1&station_id=101&component_id=1001&window=7d&format=xlsx"
import requests, re

resp = requests.get(
    "http://opendata.kosava.cloud/portal/export",
    params={
        "organization_id": 1,
        "station_id": 101,
        "component_id": 1001,
        "window": "7d",
        "format": "csv",
    },
)
resp.raise_for_status()

# Extract filename from Content-Disposition header
cd = resp.headers.get("Content-Disposition", "")
m = re.search(r'filename="(.+?)"', cd)
filename = m.group(1) if m else "export.csv"

with open(filename, "wb") as f:
    f.write(resp.content)
print(f"Saved: {filename}")
const params = new URLSearchParams({
  organization_id: "1", station_id: "101",
  component_id: "1001", window: "7d", format: "csv",
});
const resp = await fetch(`/portal/export?${params}`);
if (!resp.ok) throw new Error(await resp.text());

const blob = await resp.blob();
const cd = resp.headers.get("content-disposition") ?? "";
const filename = (cd.match(/filename="(.+?)"/) ?? [])[1] ?? "export.csv";

// Trigger browser download
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = filename;
a.click();

HVD API (/api/v1)

Javni HVD-compliant API namespace u skladu sa Sprovodbenom uredbom Komisije (EU) 2023/138 i SEPA HVD profilom. Sve rute vraćaju mašinski čitljiv JSON sa standardizovanim poljima: data_status=preliminary, aggregation_type=hourly_mean, time_start_utc/time_end_utc u ISO 8601 UTC formatu. Postojeći /meta, /stations i /measurements ugovor ostaje netaknut radi kompatibilnosti.

GET /api/v1/metadata HVD descriptor skupa podataka

Vraća kompletan HVD descriptor: schema_version, dataset_version, snapshot_id, retention_days, deklarisani data_status (preliminary), aggregation_type (hourly_mean), supported_windows, applicable_legislation (ELI link na 2023/138), licencu, i linkove na pravne stranice (license, terms, qos, contact, dataset) i dokumentaciju (docs, redoc, openapi). Pogodno za harvester-e i klijentske integracione provere.

Odgovori

StatusOpis
200Pun HVD descriptor sa licencom, retention politikom i linkovima.
503Snimak nedostupan ili nekompatibilan

Primeri koda

curl -s http://opendata.kosava.cloud/api/v1/metadata | python3 -m json.tool
import requests
m = requests.get("http://opendata.kosava.cloud/api/v1/metadata").json()
print(m["data_status"], m["retention_days"])
print(m["applicable_legislation"])
const meta = await fetch("/api/v1/metadata").then(r => r.json());
console.log(meta.license, meta.retention_days);
GET /api/v1/stations HVD stanice

Vraća sve monitoring stanice u HVD obliku (Komponenta A standarda). Svaka stanica nosi station_id (string), station_name, latitude/longitude, municipality, station_type (traffic/urban/background/industrial/rural/other), operator, active, last_updated_utc i opciona polja (elevation_m, address, start_date, end_date, notes). Podržani filteri: active, municipality (case-insensitive), station_type, bbox (min_lon,min_lat,max_lon,max_lat).

Parametri upita

NazivTipObaveznoOpis
activebooleanneFilter na aktivne stanice. true vraća samo aktivne, false samo neaktivne.
municipalitystringneFilter po imenu opštine, case-insensitive exact match.
station_typestringneFilter po HVD enum tipu stanice (traffic, urban, background, industrial, rural, other).
bboxstringneBounding box "min_lon,min_lat,max_lon,max_lat" u WGS84. Vraća stanice unutar boxa.

Primeri koda

curl -s "http://opendata.kosava.cloud/api/v1/stations?municipality=Kikinda"
stations = requests.get(
  "http://opendata.kosava.cloud/api/v1/stations",
  params={"bbox": "19,44,21,46"},
).json()
for s in stations:
  print(s["station_id"], s["station_name"], s["municipality"])
const stations = await fetch("/api/v1/stations?active=true").then(r => r.json());
stations.forEach(s => console.log(s.station_id, s.municipality));
GET /api/v1/parameters HVD rečnik parametara

Vraća kontrolisani rečnik mernih parametara (Komponenta B standarda). Svaki zapis ima parameter_code (npr. PM10, PM2.5, NO2, O3, SO2), parameter_name, unit i fiksni averaging_period=1h. Opciono: cas_number, description.

Odgovori

StatusOpis
200Niz HVD parameter zapisa.
503Snimak nedostupan ili nekompatibilan

Primeri koda

curl -s http://opendata.kosava.cloud/api/v1/parameters
params = requests.get("http://opendata.kosava.cloud/api/v1/parameters").json()
codes = [p["parameter_code"] for p in params]
# ['SO2', 'PM10', 'O3', 'NO2', 'PM2.5', ...]
const params = await fetch("/api/v1/parameters").then(r => r.json());
GET /api/v1/observations HVD satne neverifikovane vrednosti

Vraća satno upročešena merenja u HVD obliku (Komponenta C). Svaki record ima station_id, parameter_code, time_start_utc, time_end_utc, value, unit, data_status=preliminary, aggregation_type=hourly_mean, published_at_utc, updated_at_utc, coverage. Prozor se automatski seče na rolling 30 dana; meta blok odgovora navodi requested_window i actual_window plus out_of_retention_window flag. Bez filtera vraća sve stanice × svi parametri (može biti veliki payload).

Parametri upita

NazivTipObaveznoOpis
fromdatetimenePočetak prozora, ISO 8601 datetime (npr. 2026-04-01T00:00:00Z). Bez TZ tretira se kao UTC. Default: generated_at - retention_days.
todatetimeneKraj prozora, ISO 8601 datetime. Bez TZ tretira se kao UTC. Default: generated_at.
station_idstringneFilter na jednu stanicu. HVD station_id je string verzija internog ID-a.
parameter_codestringneFilter na jedan parametar (npr. PM10, PM2.5, NO2).

Primeri koda

curl -s "http://opendata.kosava.cloud/api/v1/observations?station_id=1¶meter_code=PM10"
obs = requests.get(
  "http://opendata.kosava.cloud/api/v1/observations",
  params={
    "from": "2026-04-01T00:00:00Z",
    "to": "2026-04-08T00:00:00Z",
    "parameter_code": "PM2.5",
  },
).json()
print(obs["meta"]["actual_window"])
print(len(obs["data"]), "records")
const q = new URLSearchParams({station_id: "1", parameter_code: "PM10"});
const resp = await fetch(`/api/v1/observations?${q}`).then(r => r.json());
console.log(resp.meta.out_of_retention_window);
GET /api/v1/bulk HVD bulk download index

Vraća listu bulk resursa za aktivni snapshot. Svaki zapis ima name, format, content_type, size_bytes, sha256, download_url. Bundle uključuje stations.csv/geojson, parameters.csv/json, observations CSV i Parquet (kraći ~13× od CSV-a), README.md sa data dictionary-jem i CHECKSUMS.sha256. Lazy on-demand build sa snapshot-id keyed cache-om.

Odgovori

StatusOpis
200Index bulk paketa sa SHA256 sumama.
503Snimak nedostupan ili nekompatibilan

Primeri koda

curl -s http://opendata.kosava.cloud/api/v1/bulk | python3 -m json.tool
index = requests.get("http://opendata.kosava.cloud/api/v1/bulk").json()
for r in index["resources"]:
  print(r["name"], r["size_bytes"], r["sha256"])
const idx = await fetch("/api/v1/bulk").then(r => r.json());
console.log(idx.snapshot_id, idx.resources.length);
GET /api/v1/bulk/{filename} Download bulk resursa

Servira jedan bulk fajl kao attachment. Response zaglavlja uključuju Content-Disposition (attachment; filename="..."), Content-Length, Content-Type i X-Content-SHA256 (mora se podudarati sa sha256 u indeksu).

Parametri putanje

NazivTipObaveznoOpis
filenamestringdaIme bulk resursa iz indeksa (npr. observations_hourly_preliminary_last30days.parquet).

Odgovori

StatusOpis
200Bulk fajl kao attachment sa Content-Disposition i X-Content-SHA256 zaglavljima.
404Traženi fajl ne postoji u trenutnom bulk paketu.
503Snimak nedostupan ili nekompatibilan

Primeri koda

curl -O http://opendata.kosava.cloud/api/v1/bulk/observations_hourly_preliminary_last30days.parquet
import requests, pyarrow.parquet as pq
from io import BytesIO
data = requests.get("http://opendata.kosava.cloud/api/v1/bulk/observations_hourly_preliminary_last30days.parquet").content
table = pq.read_table(BytesIO(data))
print(table.num_rows, table.column_names)
const blob = await fetch("/api/v1/bulk/stations.geojson").then(r => r.blob());
// feed blob to Leaflet, OpenLayers, etc.
GET /api/v1/dcat DCAT-AP HVD JSON-LD katalog

Vraća DCAT-AP HVD katalog kao application/ld+json sa @context i @graph od 16 nodova: jedan dcat:Catalog, foaf:Organization (publisher) i vcard:Organization (kontakt), tri dcat:Dataset (stations, parameters, observations), devet dcat:Distribution (API + CSV/GeoJSON/JSON/Parquet po datasetu), jedan dcat:DataService. Svaki Dataset/Distribution nosi dcatap:applicableLegislation (ELI 2023/138) i dcatap:hvdCategory (Earth observation and environment). Pogodno za harvest na EU/nacionalnim portalima.

Odgovori

StatusOpis
200DCAT-AP HVD katalog kao application/ld+json sa 16-node @graph.
503Snimak nedostupan ili nekompatibilan

Primeri koda

curl -s -H "Accept: application/ld+json" http://opendata.kosava.cloud/api/v1/dcat
cat = requests.get("http://opendata.kosava.cloud/api/v1/dcat").json()
datasets = [n for n in cat["@graph"] if n.get("@type") == "dcat:Dataset"]
print(len(datasets), "datasets")
const cat = await fetch("/api/v1/dcat").then(r => r.json());
// JSON-LD compatible with rdflib, jsonld.js, Apache Jena

Rečnik polja (HVD Sekcija 11)

Strukturni rečnik svakog polja iz tri komponente skupa podataka. Definicije su dostupne mašinski čitljivo na endpoint-u /api/v1/data-dictionary i ovde u tri jezika. Konstantne vrednosti i reference između komponenti su naznačene u tabelama.

GET /api/v1/data-dictionary Strukturni rečnik polja

Vraća JSON sa definicijama svih polja u tri komponente (stations, parameters, observations) plus listu zabranjenih polja. Pogodan za klijentske validacije i automatsku generaciju formi/dokumentacije.

Parametri upita

NazivTipObaveznoOpis
language string ne Jezik definicija. Jedan od: sr-Latn, sr-Cyrl, en. Default: sr-Latn.

Zabranjena polja (HVD Sekcija 5.3.2): validated, qa_flag, compliance, exceedance

§5.1 Stanice (HVD Komponenta A)

Identifikacija i geolokacija mernih mesta. Endpoint /api/v1/stations vraća listu sa svim poljima ispod; bulk distribucije su stations.csv i stations.geojson.

Naziv Tip Obavezno Konstanta Referenca Opis
station_id string da Jedinstveni identifikator merne stanice. Stabilan kroz vreme i kroz snapshot generacije; služi kao primarni ključ za stanicu u svim distribucijama i kao referenca u observations.station_id.
station_name string da Čovekoljudsko ime stanice (npr. „Kikinda Centar"). Može sadržavati lokalnu transliteraciju.
station_code string ne Operatorski kod stanice (npr. „RS1002A") koji se često koristi u izveštajnim sistemima. Dodatno stabilan identifier; nije deo HVD obaveznog skupa ali se emituje radi interoperabilnosti.
latitude decimal da Geografska širina stanice u WGS84 koordinatnom sistemu, decimalni stepen.
longitude decimal da Geografska dužina stanice u WGS84 koordinatnom sistemu, decimalni stepen.
municipality string da Naziv opštine u kojoj se stanica nalazi. Može biti null kada izvor podataka ne raspolaže ovom informacijom (polje obavezno postoji u shemi).
station_type enum da Tip lokacije stanice po HVD klasifikaciji. Dozvoljene vrednosti: traffic, urban, background, industrial, rural, other. Može biti null ako tip nije poznat.
operator string da Naziv organizacije koja operiše stanicom. Trenutno se izvodi iz organization.name na nivou portal instance.
active boolean da Da li stanica trenutno aktivno emituje merenja. true ako je stanica prisutna u aktivnom snapshotu i operativna; false ako je zaustavljena ili van mreže.
last_updated_utc datetime da Trenutak poslednjeg ažuriranja metapodataka stanice u ISO 8601 UTC formatu. Trenutno se izvodi iz manifest.generated_at (snapshot-level timestamp).
elevation_m decimal ne Nadmorska visina stanice u metrima. Opciono polje, null ako nije dostupno.
address string ne Postanska ili ulična adresa stanice. Opciono polje, null ako nije dostupno.
start_date date ne Datum početka rada stanice u ISO 8601 formatu (YYYY-MM-DD). Opciono polje.
end_date date ne Datum prestanka rada stanice u ISO 8601 formatu. null ako stanica još radi.
notes string ne Slobodan tekst sa dodatnim napomenama o stanici. Opciono polje.
network_id integer ne Identifikator merne mreže kojoj stanica pripada. Nije deo HVD obaveznog skupa ali se emituje radi navigacije po mrežama.
network_code string ne Operatorski kod merne mreže. Nije deo HVD obaveznog skupa.
§5.2 Parametri (HVD Komponenta B)

Kontrolisani rečnik mernih veličina. Endpoint /api/v1/parameters vraća niz; bulk distribucije su parameters.csv i parameters.json.

Naziv Tip Obavezno Konstanta Referenca Opis
parameter_code string da Sifra parametra (npr. PM10, PM2.5, NO2, O3, SO2). Stabilan ključ koji se referencira iz observations.parameter_code.
parameter_name string da Puno čovekoljudsko ime parametra (npr. „Particulate matter <= 2.5 um"). Trenutno fallback-uje na parameter_code dok snapshot ne počne da emituje component.name (v1.3.0).
unit string da Jedinica mere u UCUM ili sličnoj notaciji (npr. „ug.m-3" za mikrograme po kubnom metru). Konzistentna između parameters i observations distribucija.
averaging_period string da 1h Period upročešavanja vrednosti. Konstantno „1h" u v1.0 — sve vrednosti su satni proseci.
cas_number string ne CAS broj zagadjivaca (npr. „10102-44-0" za NO2). Opciono, null ako nije dostupno.
description string ne Slobodan tekst sa dodatnim opisom parametra. Opciono polje.
§5.3 Satne neverifikovane vrednosti (HVD Komponenta C)

Satno upročešena merenja sa svim stanicama i parametrima u rolling 30-day prozoru. Endpoint /api/v1/observations vraća JSON sa data + meta blokom; bulk distribucije su observations_hourly_preliminary_last30days.csv i .parquet.

Naziv Tip Obavezno Konstanta Referenca Opis
station_id string da stations.station_id Identifikator merne stanice. Referenca na stations.station_id; mora postojati u istom snapshotu.
parameter_code string da parameters.parameter_code Šifra parametra. Referenca na parameters.parameter_code; mora postojati u istom snapshotu.
time_start_utc datetime da Početak satnog intervala (uključivo) u ISO 8601 UTC formatu sa Z sufiksom. Vremenski opseg zapisa je [time_start_utc, time_end_utc).
time_end_utc datetime da Kraj satnog intervala (isključivo) u ISO 8601 UTC formatu. Uvek time_start_utc + 1h.
value decimal da Sat na koncentracija parametra na stanici, u jedinici naznačenoj poljem unit. null ako merenje nije dostupno za dati interval.
unit string da parameters.unit Jedinica mere za polje value. Konzistentno sa parameters.unit za isti parameter_code.
data_status string da preliminary Status validacije podatka. Konstantno „preliminary" — podaci nisu prošli formalnu QA/QC validaciju i nisu namenjeni regulatornoj proceni.
aggregation_type string da hourly_mean Tip agregacije vrednosti. Konstantno „hourly_mean" — vrednost predstavlja prosek u 60-minutnom intervalu [time_start_utc, time_end_utc).
published_at_utc datetime da Trenutak prvog objavljivanja vrednosti u ISO 8601 UTC. U v1.0 izvodi se iz manifest.generated_at (snapshot-level); per-record verzija dolazi sa snapshot v1.3.0.
updated_at_utc datetime da Trenutak poslednje izmene vrednosti u ISO 8601 UTC. Ako vrednost nikad nije menjana, jednako published_at_utc. Trenutno snapshot-level; per-record verzija dolazi sa snapshot v1.3.0.
coverage decimal ne Relativna pokrivenost satnog intervala u opsegu [0, 1]. Vrednost 1.0 znači punu pokrivenost (60/60 minuta), 0.5 znači pola interval. null ako sistem ne raspolaže ovom informacijom (polje obavezno postoji u shemi).
KOSAVA v7 OpenData — API v1.2.0 — Read-Only Public Data Portal — Swagger UIReDoc