{"weather":{"Lagos":{"temperature_c":30.1,"humidity_pct":74.0,"precipitation_mm":0.0,"wind_speed_kmh":11.4,"description":"Mainly clear","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":35.2,"pressure_hpa":1008.6,"cloud_cover_pct":36.0,"wind_direction_deg":229.0,"is_day":true,"icon":"clear","wmo_code":1,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":31.4,"temp_min_c":27.0,"precipitation_mm":2.3,"precipitation_probability_pct":100.0,"description":"Slight rain showers","icon":"rain"},{"date":"2026-10-25","temp_max_c":29.9,"temp_min_c":25.3,"precipitation_mm":6.2,"precipitation_probability_pct":98.0,"description":"Slight rain showers","icon":"rain"},{"date":"2026-10-26","temp_max_c":29.1,"temp_min_c":25.6,"precipitation_mm":6.4,"precipitation_probability_pct":88.0,"description":"Thunderstorm","icon":"thunder"},{"date":"2026-10-27","temp_max_c":28.7,"temp_min_c":24.1,"precipitation_mm":12.9,"precipitation_probability_pct":99.0,"description":"Thunderstorm","icon":"thunder"},{"date":"2026-10-28","temp_max_c":30.0,"temp_min_c":25.0,"precipitation_mm":3.3,"precipitation_probability_pct":100.0,"description":"Moderate drizzle","icon":"drizzle"},{"date":"2026-10-29","temp_max_c":30.6,"temp_min_c":25.3,"precipitation_mm":0.9,"precipitation_probability_pct":100.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-30","temp_max_c":30.1,"temp_min_c":26.2,"precipitation_mm":7.1,"precipitation_probability_pct":86.0,"description":"Dense drizzle","icon":"drizzle"}]},"Accra":{"temperature_c":31.0,"humidity_pct":64.0,"precipitation_mm":0.1,"wind_speed_kmh":13.6,"description":"Light drizzle","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":35.1,"pressure_hpa":1003.6,"cloud_cover_pct":39.0,"wind_direction_deg":197.0,"is_day":true,"icon":"drizzle","wmo_code":51,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":33.3,"temp_min_c":26.3,"precipitation_mm":1.4,"precipitation_probability_pct":98.0,"description":"Moderate drizzle","icon":"drizzle"},{"date":"2026-10-25","temp_max_c":31.5,"temp_min_c":25.2,"precipitation_mm":2.4,"precipitation_probability_pct":94.0,"description":"Slight rain showers","icon":"rain"},{"date":"2026-10-26","temp_max_c":30.4,"temp_min_c":25.6,"precipitation_mm":5.3,"precipitation_probability_pct":92.0,"description":"Slight rain showers","icon":"rain"},{"date":"2026-10-27","temp_max_c":29.6,"temp_min_c":24.3,"precipitation_mm":7.6,"precipitation_probability_pct":99.0,"description":"Thunderstorm","icon":"thunder"},{"date":"2026-10-28","temp_max_c":29.9,"temp_min_c":23.4,"precipitation_mm":1.5,"precipitation_probability_pct":100.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-29","temp_max_c":31.6,"temp_min_c":23.1,"precipitation_mm":0.6,"precipitation_probability_pct":100.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-30","temp_max_c":30.0,"temp_min_c":24.5,"precipitation_mm":1.7,"precipitation_probability_pct":73.0,"description":"Light drizzle","icon":"drizzle"}]},"Dakar":{"temperature_c":31.9,"humidity_pct":59.0,"precipitation_mm":0.0,"wind_speed_kmh":14.3,"description":"Partly cloudy","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":36.6,"pressure_hpa":1005.6,"cloud_cover_pct":65.0,"wind_direction_deg":5.0,"is_day":true,"icon":"cloud","wmo_code":2,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":31.9,"temp_min_c":27.5,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-25","temp_max_c":34.0,"temp_min_c":26.1,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-26","temp_max_c":31.6,"temp_min_c":27.2,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-27","temp_max_c":33.1,"temp_min_c":27.4,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-28","temp_max_c":34.8,"temp_min_c":26.0,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-29","temp_max_c":33.7,"temp_min_c":25.9,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-30","temp_max_c":33.1,"temp_min_c":24.7,"precipitation_mm":0.0,"precipitation_probability_pct":6.0,"description":"Overcast clouds","icon":"cloud"}]},"Cairo":{"temperature_c":29.7,"humidity_pct":41.0,"precipitation_mm":0.0,"wind_speed_kmh":12.1,"description":"Mainly clear","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":29.7,"pressure_hpa":1009.3,"cloud_cover_pct":40.0,"wind_direction_deg":27.0,"is_day":true,"icon":"clear","wmo_code":1,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":30.6,"temp_min_c":19.6,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Partly cloudy","icon":"cloud"},{"date":"2026-10-25","temp_max_c":28.8,"temp_min_c":19.4,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Partly cloudy","icon":"cloud"},{"date":"2026-10-26","temp_max_c":26.4,"temp_min_c":18.4,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-27","temp_max_c":27.6,"temp_min_c":17.8,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-28","temp_max_c":27.0,"temp_min_c":17.3,"precipitation_mm":0.0,"precipitation_probability_pct":8.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-29","temp_max_c":25.5,"temp_min_c":17.1,"precipitation_mm":0.0,"precipitation_probability_pct":3.0,"description":"Partly cloudy","icon":"cloud"},{"date":"2026-10-30","temp_max_c":25.0,"temp_min_c":16.1,"precipitation_mm":0.0,"precipitation_probability_pct":3.0,"description":"Partly cloudy","icon":"cloud"}]},"Nairobi":{"temperature_c":26.0,"humidity_pct":35.0,"precipitation_mm":0.0,"wind_speed_kmh":12.3,"description":"Overcast clouds","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":23.9,"pressure_hpa":839.1,"cloud_cover_pct":100.0,"wind_direction_deg":100.0,"is_day":true,"icon":"cloud","wmo_code":3,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":28.7,"temp_min_c":16.8,"precipitation_mm":0.1,"precipitation_probability_pct":59.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-25","temp_max_c":30.1,"temp_min_c":16.7,"precipitation_mm":1.0,"precipitation_probability_pct":58.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-26","temp_max_c":28.2,"temp_min_c":16.5,"precipitation_mm":14.6,"precipitation_probability_pct":93.0,"description":"Moderate rain showers","icon":"rain"},{"date":"2026-10-27","temp_max_c":24.4,"temp_min_c":16.4,"precipitation_mm":10.1,"precipitation_probability_pct":96.0,"description":"Dense drizzle","icon":"drizzle"},{"date":"2026-10-28","temp_max_c":24.7,"temp_min_c":16.2,"precipitation_mm":4.1,"precipitation_probability_pct":90.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-29","temp_max_c":25.7,"temp_min_c":16.9,"precipitation_mm":5.9,"precipitation_probability_pct":88.0,"description":"Slight rain showers","icon":"rain"},{"date":"2026-10-30","temp_max_c":24.5,"temp_min_c":15.7,"precipitation_mm":6.7,"precipitation_probability_pct":87.0,"description":"Moderate drizzle","icon":"drizzle"}]},"Johannesburg":{"temperature_c":28.6,"humidity_pct":16.0,"precipitation_mm":0.0,"wind_speed_kmh":8.7,"description":"Clear sky","timestamp":"2026-10-24T14:30:00+00:00","feels_like_c":25.1,"pressure_hpa":836.7,"cloud_cover_pct":0.0,"wind_direction_deg":240.0,"is_day":true,"icon":"clear","wmo_code":0,"source":"Open-Meteo","forecast":[{"date":"2026-10-24","temp_max_c":29.1,"temp_min_c":13.8,"precipitation_mm":0.0,"precipitation_probability_pct":0.0,"description":"Unknown conditions","icon":"cloud"},{"date":"2026-10-25","temp_max_c":29.6,"temp_min_c":15.7,"precipitation_mm":0.2,"precipitation_probability_pct":6.0,"description":"Light drizzle","icon":"drizzle"},{"date":"2026-10-26","temp_max_c":29.9,"temp_min_c":18.1,"precipitation_mm":0.0,"precipitation_probability_pct":19.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-27","temp_max_c":26.3,"temp_min_c":14.4,"precipitation_mm":6.9,"precipitation_probability_pct":49.0,"description":"Thunderstorm with slight hail","icon":"thunder"},{"date":"2026-10-28","temp_max_c":28.2,"temp_min_c":13.1,"precipitation_mm":0.0,"precipitation_probability_pct":2.0,"description":"Partly cloudy","icon":"cloud"},{"date":"2026-10-29","temp_max_c":29.2,"temp_min_c":13.8,"precipitation_mm":0.0,"precipitation_probability_pct":4.0,"description":"Overcast clouds","icon":"cloud"},{"date":"2026-10-30","temp_max_c":30.1,"temp_min_c":15.1,"precipitation_mm":0.0,"precipitation_probability_pct":29.0,"description":"Partly cloudy","icon":"cloud"}]}},"prices":{"Lagos":{"maize":330,"wheat":425,"rice":520,"currency":"USD/tonne","basis":"Import-parity Gulf landed cost, port of Lagos; diesel and FX premium included","method":"reference-baseline","vintage":"2024-12","local":{"currency":"NGN","rate_per_usd":1329.7998,"maize":438834.0,"wheat":565165.0,"rice":691496.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"},"Accra":{"maize":305,"wheat":405,"rice":545,"currency":"USD/tonne","basis":"Tema port arrivals plus Tema-Tamale freight, lower Rhine basis than Nigeria","method":"reference-baseline","vintage":"2024-12","local":{"currency":"GHS","rate_per_usd":11.6715,"maize":3560.0,"wheat":4727.0,"rice":6361.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"},"Dakar":{"maize":345,"wheat":410,"rice":565,"currency":"USD/tonne","basis":"Senegal river-valley production plus Sahel freight; thiacland premium for local rice","method":"reference-baseline","vintage":"2024-12","local":{"currency":"XOF","rate_per_usd":585.6278,"maize":202042.0,"wheat":240107.0,"rice":330880.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"},"Cairo":{"maize":335,"wheat":390,"rice":545,"currency":"USD/tonne","basis":"Domestic soft-wheat production and Nile import logistics","method":"reference-baseline","vintage":"2024-12","local":{"currency":"EGP","rate_per_usd":55.2887,"maize":18522.0,"wheat":21563.0,"rice":30132.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"},"Nairobi":{"maize":285,"wheat":435,"rice":530,"currency":"USD/tonne","basis":"Kenyan production year surplus plus Mombasa import parity for wheat","method":"reference-baseline","vintage":"2024-12","local":{"currency":"KES","rate_per_usd":129.8479,"maize":37007.0,"wheat":56484.0,"rice":68819.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"},"Johannesburg":{"maize":265,"wheat":395,"rice":505,"currency":"USD/tonne","basis":"Net-exporter basis: SAFEX-linked domestic maize, Durban import parity for rice","method":"reference-baseline","vintage":"2024-12","local":{"currency":"ZAR","rate_per_usd":16.5781,"maize":4393.0,"wheat":6548.0,"rice":8372.0},"fx_as_of":"Sat, 24 Oct 2026 00:02:31 +0000"}},"risk":{"Lagos":{"drought_risk":"MEDIUM","flood_risk":"LOW","score":28,"updated":"2026-10-24T09:20:56.710841+00:00","drivers":["2-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 26.1 mm (95th percentile 17.8 mm)","1 heavy-rain days vs 1.33 expected","10.1 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":360.3,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"LOW","weight":12,"heavy_days_recent":1,"heavy_days_expected":1.33,"max_daily_mm":26.1,"max_daily_p95_mm":17.8,"rain_3day_mm":10.1,"rain_3day_p95_mm":43.1,"max_dry_spell_days":2},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93},"Accra":{"drought_risk":"MEDIUM","flood_risk":"LOW","score":28,"updated":"2026-10-24T09:20:56.710869+00:00","drivers":["5-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 8.8 mm (95th percentile 5.9 mm)","2.5 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":79.1,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"LOW","weight":12,"heavy_days_recent":0,"heavy_days_expected":0.0,"max_daily_mm":8.8,"max_daily_p95_mm":5.9,"rain_3day_mm":2.5,"rain_3day_p95_mm":12.0,"max_dry_spell_days":5},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93},"Dakar":{"drought_risk":"MEDIUM","flood_risk":"LOW","score":28,"updated":"2026-10-24T09:20:56.710889+00:00","drivers":["7-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 19.6 mm (95th percentile 16.4 mm)","0 heavy-rain days vs 0.67 expected","0.0 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":160.0,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"LOW","weight":12,"heavy_days_recent":0,"heavy_days_expected":0.67,"max_daily_mm":19.6,"max_daily_p95_mm":16.4,"rain_3day_mm":0.0,"rain_3day_p95_mm":58.0,"max_dry_spell_days":7},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93},"Cairo":{"drought_risk":"MEDIUM","flood_risk":"LOW","score":28,"updated":"2026-10-24T09:20:56.710902+00:00","drivers":["30-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 0.0 mm (95th percentile 0.0 mm)","0.0 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":0.0,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"LOW","weight":12,"heavy_days_recent":0,"heavy_days_expected":0.0,"max_daily_mm":0.0,"max_daily_p95_mm":0.0,"rain_3day_mm":0.0,"rain_3day_p95_mm":0.0,"max_dry_spell_days":30},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93},"Nairobi":{"drought_risk":"MEDIUM","flood_risk":"LOW","score":28,"updated":"2026-10-24T09:20:56.710915+00:00","drivers":["5-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 12.1 mm (95th percentile 5.1 mm)","3.7 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":77.3,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"LOW","weight":12,"heavy_days_recent":0,"heavy_days_expected":0.0,"max_daily_mm":12.1,"max_daily_p95_mm":5.1,"rain_3day_mm":3.7,"rain_3day_p95_mm":14.9,"max_dry_spell_days":5},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93},"Johannesburg":{"drought_risk":"MEDIUM","flood_risk":"MEDIUM","score":45,"updated":"2026-10-24T09:20:56.710928+00:00","drivers":["13-day dry spell in the last 30 days","45 days missing from the window — low confidence","wettest day 36.1 mm (95th percentile 9.6 mm)","1 heavy-rain days vs 0.67 expected","0.0 mm in the last 3 days"],"components":{"drought":{"level":"MEDIUM","weight":45,"precip_recent_mm":82.7,"precip_expected_mm":null,"precip_deficit_pct":null,"precip_zscore":null},"flood":{"level":"MEDIUM","weight":45,"heavy_days_recent":1,"heavy_days_expected":0.67,"max_daily_mm":36.1,"max_daily_p95_mm":9.6,"rain_3day_mm":0.0,"rain_3day_p95_mm":36.2,"max_dry_spell_days":13},"alerts":[]},"method":{"drought":"90-day rainfall vs the seasonal baseline (ERA5 daily)","flood":"30-day heavy-rain days (>= 25 mm) vs expected","alerts":"GDACS official alerts"},"history_days":93}},"meta":{"generated_at":"2026-10-24T14:41:43.975651+00:00","weather":{"provider":"open-meteo","label":"Open-Meteo (live)","status":"live","as_of":"2026-10-24T14:30:00+00:00","fetched_at":"2026-10-24T14:41:10.065687+00:00","detail":null,"cached":true,"age_s":32.0},"prices":{"provider":"reference-baseline","label":"Reference baseline (FAO / World Bank) · live FX","status":"live","as_of":"2024-12","fetched_at":"2026-10-24T14:21:09.913257+00:00","detail":null,"cached":true,"age_s":1234.1},"risk":{"provider":"era5+gdacs","label":"Computed from the Open-Meteo forecast model's 92-day history (ERA5 archive unavailable) + GDACS alerts","status":"degraded","as_of":"2026-10-24T09:20:56.710653+00:00","fetched_at":"2026-10-24T09:20:56.710788+00:00","detail":"ERA5 archive unavailable — using the forecast model's 92-day history; 0 monitored events of 24 in feed","cached":true,"age_s":19247.3},"providers":[{"provider":"prices","ok":true,"latency_ms":0.047,"message":null,"checked_at":"2026-10-24T14:21:09.845391+00:00","consecutive_failures":0},{"provider":"risk","ok":true,"latency_ms":0.041,"message":"ERA5 archive unavailable — using the forecast model's 92-day history; 0 monitored events of 24 in feed","checked_at":"2026-10-24T14:36:09.923177+00:00","consecutive_failures":0},{"provider":"weather","ok":true,"latency_ms":0.079,"message":null,"checked_at":"2026-10-24T14:41:09.943919+00:00","consecutive_failures":0}],"stations":[{"key":"Lagos","name":"Lagos","country":"Nigeria","iso3":"NGA","currency":"NGN","lat":6.5244,"lon":3.3792,"tz":"Africa/Lagos","flag":"🇳🇬"},{"key":"Accra","name":"Accra","country":"Ghana","iso3":"GHA","currency":"GHS","lat":5.6037,"lon":-0.187,"tz":"Africa/Accra","flag":"🇬🇭"},{"key":"Dakar","name":"Dakar","country":"Senegal","iso3":"SEN","currency":"XOF","lat":14.7167,"lon":-17.4677,"tz":"Africa/Dakar","flag":"🇸🇳"},{"key":"Cairo","name":"Cairo","country":"Egypt","iso3":"EGY","currency":"EGP","lat":30.0444,"lon":31.2357,"tz":"Africa/Cairo","flag":"🇪🇬"},{"key":"Nairobi","name":"Nairobi","country":"Kenya","iso3":"KEN","currency":"KES","lat":-1.2921,"lon":36.8219,"tz":"Africa/Nairobi","flag":"🇰🇪"},{"key":"Johannesburg","name":"Johannesburg","country":"South Africa","iso3":"ZAF","currency":"ZAR","lat":-26.2041,"lon":28.0473,"tz":"Africa/Johannesburg","flag":"🇿🇦"}]}}