Data model & methods
#Sources
| Source | Coverage | Used for |
|---|---|---|
| WHO Global Dengue Surveillance | 199 countries and territories, monthly and weekly, 2014 onwards (broadest) | Country series, Indonesia national series, warnings, forecasts |
| OpenDengue V1.3 (Clarke et al., 2025) | National history since the 1920s; Indonesian provinces 2007 to 2024 | Long-run history, provinces, splicing |
| Dinas Kesehatan Kota Semarang | 177 sub-districts, monthly DHF (DBD) and DF (DD), 2016 to 2024 | Semarang risk scores and hotspots |
| World Bank | National and subnational population | Incidence per 100,000 |
| NASA POWER, NOAA CPC | Monthly climate at 33 provincial capitals; Oceanic Niño Index | Climate tests |
#Freshness
The pipeline runs every Monday at 02:17 UTC. It downloads every source, rebuilds every dataset, runs the models and 20 validation checks. If any check fails, nothing is published and the API keeps the previous data. GET /v1/status returns data_updated_at and the validation summary.
The latest month of a country is often incomplete because of reporting delays. Analyses use the latest complete month (latest_complete_month): never the current month, and trailing months far below the recent level are excluded.
#Cleaning applied to the source data
- Future-dated rows published as zero placeholders are dropped.
- Negative weekly values (retrospective corrections of cumulative counts) are absorbed into earlier months of the same year. No month is negative and annual totals are unchanged. The count is reported in
provenance.negative_corrections_absorbed. - Splicing: a WHO series is extended backwards with OpenDengue months only when both sources agree on the months they share (median ratio 0.67 to 1.5). Request it with
include_history=true.
#Warning levels
warning.level combines five signals into points:
| Signal | Points |
|---|---|
| Endemic-channel zone | Safety 0.5, Alert 1.5, Epidemic 3 |
| Outbreak score (Farrington-style) | above 0.5: 1, above 1: 2 |
| CUSUM alarm while above the median | 1 |
| Probability of crossing the epidemic threshold in 3 months (only when the forecast beats a naive benchmark) | 20%: 1, 50%: 2 |
| Momentum of 30% or more above the median | 1 |
| Level | Points | Meaning |
|---|---|---|
normal | below 1.5 | Within the usual range |
watch | 1.5 | Early signs worth monitoring |
alert | 3 (or Epidemic zone) | Several signals point to a rise |
outbreak | 4.5 | Strong, converging outbreak signals |
Places with irregular reporting (batch reports, long runs of zeros) are capped at watch and flagged with irregular-reporting. warning.status is insufficient when there are fewer than 36 consecutive months or too few recent cases; reason explains which.
#Endemic zones
For each calendar month, the five previous complete years give a median, a 3rd quartile and an epidemic threshold (geometric mean + 1.96 SD of log(cases + 1)).
endemic_zone | Meaning |
|---|---|
sukses | Success: at or below the median |
aman | Safety: median to 3rd quartile |
waspada | Alert: 3rd quartile to epidemic threshold |
epidemi | Epidemic: above the threshold |
The values are kept in Indonesian because they follow the Indonesian Ministry of Health terminology.
#Forecasts
/forecast endpoints return a six-month ensemble of seasonal naive, damped Holt-Winters and ridge harmonic regression with autoregressive terms. Weights come from a 24-origin rolling backtest. lower_80/upper_80 and lower_95/upper_95 are built from the ensemble's own backtest errors. backtest.coverage_80 reports how often the 80% range actually held. p_exceed_threshold is the probability that a month exceeds its epidemic threshold.
backtest.mase below 1 means the forecast beats repeating last year's value over the same months. skilled: false means the forecast is shown but not used for warnings.
#Units and conventions
- Counts are integers (reported cases or deaths).
nullmeans not reported, which is different from0. incidence_per_100k: cases per 100,000 people in the year.case_fatality_pct: deaths ÷ cases × 100.- Months are
YYYY-MM; timestamps are ISO 8601 UTC. - Field names are
snake_caseand stable withinv1.
Methods are described in full on the website's Model Lab and glossary.