Публичный REST API версии 1: чтение без ключей, JSON по умолчанию; приём данных станций — POST с ключом станции. Спецификация OpenAPI 3.1 генерируется из тех же схем, что проверяют запросы и ответы сервера.
Базовый адрес https://havo.tj
Авторизация Для чтения не требуется (ограничение 120 запросов в минуту с одного IP). Приём данных станций — заголовок Authorization: Bearer <ключ станции>, отдельный лимит 60 запросов в минуту на станцию.
CORS Разрешены запросы с любых сайтов (Access-Control-Allow-Origin: *). /api/v1/stations /api/v1/stations/{slug}/measurements /api/v1/index/current /api/v1/exceedances /api/v1/forecast/{slug} /api/v1/silam/{slug} /api/v1/silam/layers /api/v1/alerts /api/v1/alerts/{id}/xml /api/v1/news /api/v1/news/rss.xml /api/v1/regions /api/v1/districts /api/v1/ingest/{code} Качество воздуха GET /api/v1/stationsкэш 60 s
Список станций мониторинга Публичные станции (кроме выведенных из эксплуатации) как GeoJSON FeatureCollection с текущим уровнем индекса; 0 — нет данных или устарело.
Ответы
200 application/jsonУспешный ответ
type "FeatureCollection" обяз. features object[] обяз. type "Feature" обяз. id integer обяз. geometry object обяз. type "Point" обяз. coordinates [number, number] обяз. properties object обяз. id integer обяз. slug string обяз. code string обяз. — Station code, e.g. DU-01 name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string kind "air" | "meteo" | "combined" обяз. status "active" | "suspended" | "decommissioned" обяз. region object | null обяз. tg string ru string en string level integer обяз. — Air quality level 1–5 (1–6 for six-category scales such as US AQI); 0 — no data indexValue number | null обяз. — Continuous index value (level + fraction) indexTime string (date-time) | null обяз. — Time of the index value GET /api/v1/stations/{slug}/measurementsкэш 60 s
Ряды измерений станции Часовые (24h, 7d) или суточные по местному времени (30d, 1y) средние валидных измерений с min/max и числом значений. CSV — параметром format=csv. Значения и поле unit — в единице отображения, выбранной Агентством (µg/m³ или mg/m³).
Параметры Параметр Где Тип Описание slugобяз. path string Адрес станции (поле slug из списка станций) rangequery 24h | 7d | 30d | 1y = 24h Период: 24h, 7d, 30d или 1y pollutantquery string Код вещества (PM25, PM10, NO2, SO2, CO, O3, NO, CH2O, C6H5OH, HF, TSP, CO2, TVOC); без параметра — все formatquery json | csv = json json или csv
Пример запроса
curl "https://havo.tj/api/v1/stations/dushanbe-centre/measurements?range=7d&pollutant=PM25"Открыть в браузере → → Ответы
200 application/jsonУспешный ответ
station object обяз. id integer обяз. slug string обяз. code string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string range "24h" | "7d" | "30d" | "1y" обяз. from string (date-time) обяз. — ISO 8601 timestamp (UTC) to string (date-time) обяз. — ISO 8601 timestamp (UTC) aggregation "hour" | "day" обяз. — hour for 24h/7d, day (local time) for 30d/1y timezone "Asia/Dushanbe" обяз. series object[] обяз. pollutant object обяз. id integer обяз. code string обяз. shortName string обяз. unit string обяз. — Display unit configured by the Agency: µg/m³ or mg/m³ (CO always mg/m³; CO2 ppm, TVOC ppb). Values are converted to it decimals integer обяз. points object[] обяз. t string (date-time) обяз. — Start of the hour/day v number | null обяз. — Mean of valid measurements, in `unit` min number | null обяз. max number | null обяз. n integer обяз. — Number of measurements in the bin 200 text/csvCSV (UTF‑8 с BOM): time_utc, time_local, pollutant, value, min, max, n
400 application/jsonНекорректные параметры
404 application/jsonОбъект не найден
GET /api/v1/index/currentкэш 60 s
Текущий индекс по станциям Последний рассчитанный индекс каждой публичной станции: уровень, значение, определяющее вещество, под‑индексы и признак устаревания (старше 6 часов). Для шкалы RATIO_TO_LIMIT — показатели методики Агентства (indicators): суммация NO₂+SO₂, максимальные разовые концентрации с кратностью ПДКм.р., признаки ВЗ/ЭВЗ; units — единицы отображения по веществам.
Параметры Параметр Где Тип Описание scalequery string Код шкалы: NATIONAL_OPERATIONAL (по умолчанию), WHO_24H или IZA
Ответы
200 application/jsonУспешный ответ
scale object обяз. code string обяз. kind "breakpoints" | "ratio_to_limit" | "iza" обяз. levels object[] обяз. level integer обяз. color string обяз. — Hex colour label object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string lo number hi number | null generatedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) units object обяз. — Display unit per pollutant code (µg/m³ or mg/m³ as configured by the Agency; ppm, ppb) stations object[] обяз. id integer обяз. slug string обяз. code string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string level integer обяз. — Air quality level 1–5 (1–6 for six-category scales such as US AQI); 0 — no data value number | null обяз. time string (date-time) | null обяз. stale boolean обяз. — Index older than 6 hours dominantPollutant string | null обяз. — Pollutant code with the worst sub-index subIndices object обяз. value number обяз. — Concentration used for the sub-index, in the display unit level integer обяз. index number обяз. — Continuous sub-index; for RATIO_TO_LIMIT — ratio to the daily limit indicators object | null обяз. no2so2Sum number | null обяз. — NO2 + SO2 summation: sum of the daily-limit ratios; null when one of them is not measured highPollution boolean обяз. — High pollution (ВЗ): a pollutant reached 10 single limits extremeHighPollution boolean обяз. — Extremely high pollution (ЭВЗ): a pollutant reached 50 single limits maxSingle object обяз. value number обяз. — Maximum single (hourly) concentration of the last 24 hours, in the display unit ratio number | null обяз. — Ratio to the single limit; null without a limit flagged object обяз. — Pollutants with high/extremely high pollution: ratio to the single limit 404 application/jsonОбъект не найден
GET /api/v1/exceedancesкэш 60 s
Активные превышения порогов Открытые события превышения по правилам уведомлений Агентства (канал «портал»).
Ответы
200 application/jsonУспешный ответ
generatedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) events object[] обяз. id integer обяз. startedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) station object обяз. id integer обяз. slug string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string rule string обяз. kind "pollutant" | "index" обяз. pollutant string | null обяз. unit string | null обяз. value number | null обяз. threshold number обяз. level integer | null обяз. Прогнозы GET /api/v1/forecast/{slug}кэш 300 s
Прогноз погоды для точки Почасовой ряд и суточные агрегаты SmartMet Server; время запуска модели и производитель данных.
Параметры Параметр Где Тип Описание slugобяз. path string Адрес точки прогноза, например dushanbe hoursquery integer = 72 Число часов почасового ряда (1–240) daysquery integer = 10 Число дней суточного прогноза (1–16)
Ответы
200 application/jsonУспешный ответ
location object обяз. slug string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string lat number обяз. lon number обяз. region object | null обяз. tg string ru string en string producer string | null обяз. — SmartMet producer, e.g. ecmwf originTime string (date-time) | null обяз. — Model run time fetchedAt string (date-time) | null обяз. timeZone "Asia/Dushanbe" обяз. hourly object[] обяз. time string (date-time) обяз. — ISO 8601 timestamp (UTC) t number | null — Air temperature, °C ws number | null — Wind speed, m/s wd number | null — Wind direction, degrees gust number | null — Wind gust, m/s rh number | null — Relative humidity, % p number | null — Pressure, hPa dew number | null — Dew point, °C precip number | null — Precipitation, mm/h cloud number | null — Total cloud cover, % symbol integer | null — FMI SmartSymbol code (1xx — night variant) daily object[] обяз. date string (date-time) обяз. — Local midnight (UTC+5) of the day tmax number | null tmin number | null precipSum number | null — Daily precipitation, mm ws number | null — Max wind speed, m/s cloud number | null symbol integer | null 404 application/jsonОбъект не найден
GET /api/v1/silam/{slug}кэш 600 s
Прогноз качества воздуха SILAM для точки Почасовые концентрации и уровни по веществам плюс суточная сводка (среднее за местные сутки, уровень по худшему веществу).
Параметры Параметр Где Тип Описание slugобяз. path string Адрес точки прогноза, например dushanbe
Ответы
200 application/jsonУспешный ответ
location object обяз. slug string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string lat number обяз. lon number обяз. run object | null обяз. originTime string (date-time) обяз. — ISO 8601 timestamp (UTC) fetchedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) units object обяз. — Unit per pollutant code hourly object обяз. — Hourly [time, value, level] per pollutant days object[] обяз. date string обяз. — YYYY-MM-DD, local time level integer обяз. — Air quality level 1–5 (1–6 for six-category scales such as US AQI); 0 — no data dominantPollutant string | null обяз. means object обяз. — Daily mean per pollutant code 404 application/jsonОбъект не найден
GET /api/v1/silam/layersкэш 600 s
Каталог растровых слоёв SILAM Границы сетки и PNG‑кадры по веществам и часам последнего прогона — для наложения на карту.
Ответы
200 application/jsonУспешный ответ
run object | null обяз. originTime string (date-time) обяз. — ISO 8601 timestamp (UTC) fetchedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) hours integer обяз. bounds object | null обяз. — Grid bounds in degrees for image placement west number обяз. south number обяз. east number обяз. north number обяз. pollutants object[] обяз. code string обяз. frames object[] обяз. time string (date-time) обяз. — ISO 8601 timestamp (UTC) url string обяз. — Relative URL of the PNG layer max number | null обяз. — Maximum concentration in the domain Предупреждения GET /api/v1/alertsкэш 60 s
Предупреждения CAP Нормализованный список предупреждений SmartMet Alert на выбранном языке (с фолбэком) или GeoJSON полигонов для карты.
Параметры Параметр Где Тип Описание activequery 1 1 — только действующие сейчас regionquery string Код региона предупреждений (DU, SU, KT, GB, RRP) langquery tg | ru | en = tg Язык текстов: tg, ru или en daysquery integer = 7 Горизонт в днях (1–14) formatquery json | geojson = json json или geojson
Ответы
200 application/jsonУспешный ответ
generatedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) lang "tg" | "ru" | "en" обяз. count integer обяз. alerts object[] обяз. id integer обяз. identifier string обяз. — CAP identifier sent string (date-time) обяз. — ISO 8601 timestamp (UTC) msgType "Alert" | "Update" | "Cancel" | "Ack" | "Error" обяз. language string обяз. event string обяз. headline string обяз. description string | null обяз. instruction string | null обяз. severity "Extreme" | "Severe" | "Moderate" | "Minor" | "Unknown" обяз. color "red" | "orange" | "yellow" | "none" обяз. colorHex string обяз. urgency string обяз. certainty string обяз. effective string (date-time) | null обяз. onset string (date-time) | null обяз. expires string (date-time) | null обяз. start string (date-time) обяз. — ISO 8601 timestamp (UTC) end string (date-time) | null обяз. active boolean обяз. upcoming boolean обяз. regions object[] обяз. code string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string areas string[] обяз. — areaDesc values web string | null обяз. xml string обяз. — URL of the original CAP XML 200 application/geo+jsonGeoJSON при format=geojson
type "FeatureCollection" обяз. generatedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) features object[] обяз. type "Feature" обяз. id string обяз. geometry object обяз. type string обяз. coordinates any[] обяз. properties object обяз. id integer обяз. identifier string обяз. event string обяз. headline string обяз. severity string обяз. level integer обяз. color string обяз. start string (date-time) обяз. — ISO 8601 timestamp (UTC) end string (date-time) | null обяз. active boolean обяз. region string | null обяз. areaDesc string обяз. href string обяз. Параметры Параметр Где Тип Описание idобяз. path string Идентификатор предупреждения из списка
Ответы
200 application/cap+xmlИсходное сообщение CAP 1.2
404 application/jsonОбъект не найден
Новости Параметры Параметр Где Тип Описание localequery tg | ru | en = tg Язык: tg, ru или en pagequery integer = 1 Номер страницы pageSizequery integer = 12 Размер страницы (1–50) categoryquery string Slug рубрики
Ответы
200 application/jsonУспешный ответ
locale "tg" | "ru" | "en" обяз. page integer обяз. pageSize integer обяз. total integer обяз. items object[] обяз. id integer обяз. slug string обяз. title string обяз. excerpt string обяз. publishedAt string (date-time) | null обяз. updatedAt string (date-time) обяз. — ISO 8601 timestamp (UTC) pinned boolean обяз. category object | null обяз. slug string обяз. name string обяз. cover string | null обяз. — Absolute URL of the cover image url string обяз. — Absolute URL of the article География GET /api/v1/regionsкэш 600 s
Административные границы: области Области, Душанбе и РРП с упрощёнными полигонами, центроидами, числом станций и худшим текущим уровнем индекса (0 — нет данных). Кэш 10 минут, ETag.
Ответы
200 application/jsonУспешный ответ
type "FeatureCollection" обяз. features object[] обяз. type "Feature" обяз. id integer обяз. geometry object обяз. type "MultiPolygon" обяз. coordinates any[] обяз. properties object обяз. id integer обяз. code string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string stationsCount integer обяз. — Public stations located inside the unit level integer обяз. — Worst current index level among the unit's stations; 0 — no data or stale sortOrder integer обяз. centroid [number, number] | null обяз. GET /api/v1/districtsкэш 600 s
Административные границы: районы Районы и города областного подчинения с упрощёнными полигонами, кодом области, числом станций и худшим текущим уровнем индекса. Единицы без загруженной геометрии не включаются.
Ответы
200 application/jsonУспешный ответ
type "FeatureCollection" обяз. features object[] обяз. type "Feature" обяз. id integer обяз. geometry object обяз. type "MultiPolygon" обяз. coordinates any[] обяз. properties object обяз. id integer обяз. code string обяз. name object обяз. — Localized text: Tajik (tg), Russian (ru), English (en) tg string ru string en string stationsCount integer обяз. — Public stations located inside the unit level integer обяз. — Worst current index level among the unit's stations; 0 — no data or stale regionId integer обяз. — Parent region id regionCode string обяз. — Parent region code (DU, RRP, SU, KT, GB) Приём данных станций POST /api/v1/ingest/{code}
Приём измерений от станции Логгер, агент станции или вендорское ПО отправляют JSON‑массив измерений (до 1000 за запрос). Время — ISO 8601 с зоной или местное (Asia/Dushanbe); вещества — коды PM25, PM10, NO2, SO2, CO, O3 или синонимы; единица по умолчанию — единица ввода станции. Значения приводятся к единице вещества, проходят правило диапазона QC и записываются по ключу время/вещество/осреднение — повторная отправка идемпотентна, решения оператора сохраняются. Ответ содержит число принятых и отклонённых записей и причины по каждой. После записи пересчитывается индекс и правила уведомлений.
Параметры Параметр Где Тип Описание codeобяз. path string Код станции из реестра (например DU-01)
Авторизация: Ключ API станции из карточки станции в панели администратора; передаётся заголовком Authorization: Bearer <ключ>. В базе хранится только хэш ключа.
Тело запроса
application/jsonobject[] | object
Пример запроса
curl -X POST "https://havo.tj/api/v1/ingest/DU-01" \
-H "Authorization: Bearer <station-api-key>" \
-H "Content-Type: application/json" \
-d '[
{
"time": "2026-10-18T07:00:00Z",
"pollutant": "PM25",
"value": 42.5
},
{
"time": "2026-10-18 12:00",
"pollutant": "pm2.5",
"value": "12,5",
"unit": "µg/m³"
},
{
"time": "2026-10-18T07:00:00Z",
"pollutant": "NO2",
"value": 10,
"unit": "ppb",
"flag": "valid"
},
{
"time": "2026-10-18T07:00:00Z",
"pollutant": "CO",
"value": null,
"flag": "missing"
}
]'Ответы
200 application/jsonПринята хотя бы одна запись (причины отклонённых — в errors)
station object обяз. id integer обяз. code string обяз. slug string обяз. received integer обяз. — Records in the request accepted integer обяз. — Records stored (distinct time/pollutant/averaging keys) rejected integer обяз. — Records rejected; see errors inserted integer обяз. — New rows updated integer обяз. — Existing rows overwritten (idempotent re-sends) skippedLocked integer обяз. — Rows kept as decided by an operator (qc_locked) invalidRange integer обяз. — Accepted values outside the QC range, stored with flag invalid duplicates integer обяз. — Records superseded by a later record with the same key from string (date-time) | null обяз. to string (date-time) | null обяз. pollutants string[] обяз. — Pollutant codes of accepted records errors object[] обяз. — Per-record reasons for rejected and superseded records index integer обяз. — Index of the record in the request array message string обяз. — Reason: time, futureTime, tooOld, unknownPollutant:X, pollutantNotConfigured:X, emptyValue, value:X, unit:X, unitConversion:X, averagingMin:X, duplicate 400 application/jsonНекорректные параметры
error string обяз. — unauthorized | station_inactive | invalid_json | validation | payload_too_large | rate_limited message string issues object[] path string обяз. message string обяз. 401 application/jsonНет заголовка Authorization или ключ не подходит к коду станции
error string обяз. — unauthorized | station_inactive | invalid_json | validation | payload_too_large | rate_limited message string issues object[] path string обяз. message string обяз. 403 application/jsonСтанция приостановлена или выведена из эксплуатации
error string обяз. — unauthorized | station_inactive | invalid_json | validation | payload_too_large | rate_limited message string issues object[] path string обяз. message string обяз. 413 application/jsonТело больше 2 МБ
error string обяз. — unauthorized | station_inactive | invalid_json | validation | payload_too_large | rate_limited message string issues object[] path string обяз. message string обяз. 422 application/jsonНи одна запись не принята — см. errors
station object обяз. id integer обяз. code string обяз. slug string обяз. received integer обяз. — Records in the request accepted integer обяз. — Records stored (distinct time/pollutant/averaging keys) rejected integer обяз. — Records rejected; see errors inserted integer обяз. — New rows updated integer обяз. — Existing rows overwritten (idempotent re-sends) skippedLocked integer обяз. — Rows kept as decided by an operator (qc_locked) invalidRange integer обяз. — Accepted values outside the QC range, stored with flag invalid duplicates integer обяз. — Records superseded by a later record with the same key from string (date-time) | null обяз. to string (date-time) | null обяз. pollutants string[] обяз. — Pollutant codes of accepted records errors object[] обяз. — Per-record reasons for rejected and superseded records index integer обяз. — Index of the record in the request array message string обяз. — Reason: time, futureTime, tooOld, unknownPollutant:X, pollutantNotConfigured:X, emptyValue, value:X, unit:X, unitConversion:X, averagingMin:X, duplicate 429 application/jsonПревышен лимит запросов станции (см. Retry-After)
error string обяз. — unauthorized | station_inactive | invalid_json | validation | payload_too_large | rate_limited message string issues object[] path string обяз. message string обяз. Данные — по лицензии CC BY 4.0 с указанием источника; прогнозы FMI — с указанием Финского метеорологического института.
Для сайтов без разработки есть iframe‑виджеты /embed/aqi, /embed/forecast и /embed/alerts (см. «Открытые данные»).