SafeSkies 🌦️

Smarter Weather. Safer World.

Community Weather & Disaster Intelligence Platform β€” Real-time hyperlocal alerts with offline SMS fallback for vulnerable and rural communities.

Live Demo | Web Dashboard | API Docs


Inspiration

Every year, millions in East Africa, South Asia, and Southeast Asia face floods, cyclones, and heatwaves with hours of warning β€” or none at all. While developed nations have sophisticated meteorological networks, rural communities often lack:

  • Real-time, hyperlocal weather alerts
  • Offline communication channels when internet fails
  • AI-driven risk prediction (not just generic national forecasts)
  • Accessibility for low-literacy, low-connectivity users

In 2024, over 1.2 billion people globally live without reliable access to early warning systems. SafeSkies closes that gap.

We were inspired by:

  • UN Sustainable Development Goal 13 (Climate Action) and Goal 11 (Resilient Communities)
  • Real-world gaps in disaster preparedness in regions like Kenya, Uganda, and Bangladesh
  • The fact that SMS reaches phones that apps never will β€” even in areas with 2G-only connectivity
  • Satellite data (NASA FIRMS, NOAA ERA5) now openly available but rarely connected to community action

Our insight: Build one platform that works online, offline, and everywhere in between. Use the phone as the primary interface, SMS as the fallback lifeline.


What It Does

SafeSkies is a three-layer system that delivers weather intelligence and disaster alerts through every available channel:

1. Flutter Mobile App (User-facing)

  • Live map showing your location, risk zones (colour-coded circles), and active alert pins
  • Risk banner at the top β€” bold, colour-coded (GREEN / YELLOW / RED / BLACK) β€” says your hazard type and what to do
  • 24-hour forecast with charts β€” precipitation trend, temperature, wind
  • Offline mode β€” works perfectly on airplane mode; cached weather + cached alerts from the last 24h
  • Report hazards β€” submit crowd-sourced flood/wind damage reports with GPS location; they validate and escalate in real-time
  • Settings β€” register your phone number (for SMS) and preferred language (English / Swahili)

2. Python FastAPI Backend (Brain)

  • Weather ingestion β€” pulls from Open-Meteo every 15 minutes; zero API key needed
  • Satellite feeds β€” NASA FIRMS (active fire/flood markers), NOAA ERA5 (historical climate data)
  • AI risk scorer β€” rule-based (ships Hour 3) upgradeable to XGBoost (Hour 18+)
    • Inputs: precipitation, soil moisture, wind speed, temperature anomaly, elevation
    • Output: risk score 0.0 (safe) to 1.0 (critical) + hazard label (flood / cyclone / heatwave)
  • Alert dispatcher β€” when risk crosses HIGH threshold, simultaneously:
    • Sends FCM push to registered mobile devices
    • Sends SMS via Africa's Talking (SMS-only communities)
    • Broadcasts to responder dashboard via WebSocket
  • SMS webhook β€” listens for inbound SMS; replies to "WEATHER" keyword with current risk + advice
  • Deduplication β€” never spams the same zone twice within 2 hours

3. React Web Dashboard (Responder view)

  • Live map with alert overlays, risk heatmaps, and crowd report pins
  • Alert detail panel β€” click any alert to see severity, affected zones, evacuation routes
  • Real-time sync β€” responders mark alerts as "responding" or "resolved"; updates push to all dashboards
  • Crowd reports feed β€” validated hazard reports sorted by severity and time
  • Stats bar β€” active alert count, highest severity, zones at risk

4. SMS Gateway (Offline lifeline)

  • Powered by Africa's Talking (covers 40+ African countries)
  • Any phone can text "WEATHER" and get back a 160-char forecast + risk level
  • Works on 2G, feature phones, no app needed
  • Keyword-based: WEATHER β†’ forecast reply, HELP β†’ command list, STOP β†’ unsubscribe

How We Built It

Tech Stack

Layer Technology Why
Mobile Flutter / Dart One codebase for iOS + Android; flutter_map for OpenStreetMap (no API key); sqflite for offline cache
Web React 18 + Next.js + shadcn/ui TypeScript safety; Tailwind CSS for rapid design; shadcn components for polish
Backend Python FastAPI Type hints + async/await; minimal boilerplate; deploys to Railway in 1 click
Database SQLite (dev) / PostgreSQL (prod) SQLite = zero setup; PostGIS for geo queries at scale
Queue Redis + Celery Background task scheduling (ingest every 15m), alert deduplication
Push Firebase Cloud Messaging Free tier; handles 10M+ pushes; integrates with Flutter via flutterfire
SMS Africa's Talking API Covers 40+ African countries; sandbox free for testing
Maps flutter_map + Leaflet.js Both use OpenStreetMap; no vendor lock-in; free tiles
Deployment Railway (backend) + Vercel (web) Both free tier; auto-deploy from GitHub; gives production URLs instantly
ML scikit-learn / XGBoost Trained on NOAA ERA5 historical data; exported as .pkl; loaded at startup

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Clients                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚ Flutter App      β”‚ Web Dashboard    β”‚ SMS Gateway      β”‚    β”‚
β”‚ (Android/iOS)    β”‚ (React + Next)   β”‚ (Inbound msgs)   β”‚    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
         β”‚                  β”‚                    β”‚             β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
                      β”‚ HTTPS                                  β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
         β”‚   API Gateway (FastAPI) β”‚ ← Rate limit, auth       β”‚
         β”‚   Routers:              β”‚                           β”‚
         β”‚  - /v1/forecast         β”‚                           β”‚
         β”‚  - /v1/alerts/*         β”‚                           β”‚
         β”‚  - /v1/reports          β”‚                           β”‚
         β”‚  - /v1/responder/*      β”‚                           β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
                    β”‚                                           β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
         β”‚                                    β”‚                β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
    β”‚ Ingestion   β”‚   β”‚ ML Scorer    β”‚   β”‚Alert Dispatch   β”‚   β”‚
    β”‚ (Open-Meteo)β”‚   β”‚(XGBoost)     β”‚   β”‚(FCM, SMS, WS)   β”‚   β”‚
    β”‚             β”‚   β”‚              β”‚   β”‚                β”‚   β”‚
    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
         β”‚                   β”‚                  β”‚            β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
                             β”‚                               β”‚
                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
                 β”‚   Data Layer           β”‚                  β”‚
                 β”œβ”€ PostgreSQL (zones,    β”‚                  β”‚
                 β”‚   weather_snapshots,   β”‚                  β”‚
                 β”‚   alerts, subscriptions)                  β”‚
                 β”œβ”€ Redis (alert queue)   β”‚                  β”‚
                 β”œβ”€ Celery (task sched)   β”‚                  β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
                                                             β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
         β”‚   External APIs (all free tier)     β”‚            β”‚
         β”œβ”€ Open-Meteo (weather, no key)       β”‚            β”‚
         β”œβ”€ NASA FIRMS (satellite fire/flood)  β”‚            β”‚
         β”œβ”€ Africa's Talking (SMS)             β”‚            β”‚
         β”œβ”€ Firebase Admin SDK (FCM)           β”‚            β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Implementation Details

Flutter App (Member B)

  • State management: Provider + ChangeNotifier for weather, alerts, offline state
  • Offline cache: sqflite stores last forecast + alerts; detects connectivity via connectivity_plus
  • Map: flutter_map + flutter_map_location_marker for real-time user position
  • UI: shadcn/ui component library ported to Flutter via custom Dart widgets; Tailwind-style colour tokens (BLUE / AMBER / RED)
  • FCM setup: FlutterFire CLI; saves device token on first run
  • Mock API: api_service.dart has USE_MOCK flag; toggles between hardcoded JSON and live HTTP calls

Python Backend (Member A)

  • Ingestion: APScheduler runs ingest_weather() every 15 minutes; fetches Open-Meteo + FIRMS; stores in weather_snapshots table
  • Risk scoring:
    • Rule-based (Hour 3): precip > 30mm β†’ +0.3, wind > 50kph β†’ +0.2, humidity > 85% β†’ +0.1; clamp 0–1
    • XGBoost (Hour 18): trained on NOAA ERA5; features engineered from weather_snapshots; model.predict(features) β†’ probability
    • Output: score, label (LOW/MEDIUM/HIGH/CRITICAL), hazard type
  • Alert dispatch: Celery task triggered on score change; queries subscriptions table; fans out to FCM, SMS, WebSocket
  • SMS webhook: Africa's Talking POSTs inbound messages to /v1/alerts/sms; if text=="WEATHER", query user's location, fetch latest forecast, reply via Africa's Talking send API
  • Deployment: Dockerfile + Railway; stores DATABASE_URL + API keys in environment variables

React Web Dashboard (Member A)

  • shadcn/ui components: Button, Card, Badge, Dialog, Select, Input, Textarea
  • Map: Leaflet.js via react-leaflet; displays GeoJSON alert zones + crowd report markers
  • Real-time: Socket.io-client listens for /alert-updates and /report-updates channels; auto-refreshes map on new data
  • Charts: Recharts for 24h forecast sparkline (precipitation bar chart, temperature line)
  • Auth: Uses JWT tokens from /v1/auth/login endpoint (optional for hackathon; can use anonymous mode)
  • PWA: service-worker.js caches API responses + static assets; shows "Offline β€” using cached data" banner when disconnected

SMS Integration

  • Inbound: Africa's Talking webhook β†’ /v1/alerts/sms endpoint
  • Processing: Extract phone number + text; regex match keywords (WEATHER, HELP, STOP)
  • Response: Query subscriptions table for user's location; fetch latest weather + risk; format into 160-char SMS; call Africa's Talking send API
  • Sandbox vs production: Sandbox = test free; production = pay-as-you-go (cheap in Africa)

Challenges We Ran Into

1. API Contract Lock-In (Hour 1 blocker)

Challenge: If the JSON shapes aren't nailed down before Hour 1, both members build in parallel and code doesn't plug together at Hour 12.

Solution: We spent 30 minutes writing the API contract in a shared table (Section 3 of the scope document). Member B created Dart model classes that exactly matched the JSON. Member A built FastAPI Pydantic models from the same spec. When we swapped the stub for the live API, everything Just Worked.

Learning: Contracts > code. Lock it, then code.


2. Offline Caching vs Real-time Sync

Challenge: How to balance showing cached data (for offline resilience) with always showing the freshest alerts (for safety)?

Solution:

  • Cache all API responses to sqflite/localStorage with a timestamp
  • On app start, check connectivity_plus:
    • If online: fetch fresh data, write to cache, display fresh
    • If offline: read from cache, show offline banner + cached timestamp
  • If cached data is older than 2 hours, show a warning: "This alert may be outdated β€” connect to update"
  • On reconnect (monitor via connectivity_plus stream), auto-refresh

This gives us resilience + freshness without the complexity of sync protocols.


3. SMS Keyword Parsing vs Spam

Challenge: The Africa's Talking webhook receives all inbound SMS. If we reply to everything, it's spam. How to distinguish legitimate WEATHER requests from other messages?

Solution:

  • Only reply to exact keywords: WEATHER, HELP, STOP, ALERT (future)
  • Store a dedup key (phone + keyword + timestamp) in Redis; ignore if seen in last 5 minutes
  • For unknown messages, reply once: "Send WEATHER for forecast or HELP for commands"
  • Don't send automated alerts via SMS to unsolicited numbers β€” only to opted-in subscriptions

This keeps us compliant and avoids SMS flooding.


4. Risk Scoring Trade-off: Accuracy vs Speed

Challenge: XGBoost takes time to train (hours if doing it during the hackathon). Rule-based is simple but feels naive.

Solution: Ship rule-based at Hour 3, upgrade to XGBoost at Hour 18 if time allows.

  • Rule-based gives us a working system immediately; judges see it working
  • XGBoost adds "AI" credibility if we have time; if not, rule-based is still honest and explainable
  • We pre-trained the XGBoost model on public NOAA data before the hackathon started, then just loaded the pickle at startup

This is the right call for a hackathon: working simple > broken complex.


5. Flutter Map Performance with Hundreds of Alerts

Challenge: flutter_map can lag if you render 500+ marker pins on the map at once.

Solution:

  • Cluster nearby markers using flutter_map_supercluster package (adds 1 line of code)
  • Only fetch alerts within the current map bounding box (pass bbox to API)
  • Debounce map pan/zoom events to avoid hammer-calling the API (use Debounce from rxdart)
  • Pre-render alert circles as GeoJSON Polygon features (single layer) instead of individual Marker widgets (vastly faster)

6. Deployment Keys & Secrets

Challenge: How to share the .env safely without leaking API keys to GitHub?

Solution:

  • Never commit .env files β€” use .env.example with placeholder values
  • Store real secrets in Railway/Vercel environment variable dashboards (web UI, encrypted at rest)

  • Rotate Africa's Talking key immediately after hackathon submission


Accomplishments We're Proud Of

🎯 1. Unified Multi-Channel Architecture

Built a system where the same alert can reach users via:

  • Push notification (app always-on)
  • SMS (offline, 2G, feature phones)
  • Web dashboard (responder coordination)
  • In-app banner (when app is open) -used multiple Apis

🌍 2. True Offline Functionality

The Flutter app works offline. Not "limited" offline β€” fully offline. You can:

  • See the last 24h of cached weather
  • View active alerts
  • Submit hazard reports locally (queue for upload when online)
  • All without any server connection

We tested this by literally switching to airplane mode mid-demo. It just works.


πŸ“‘ 3. SMS Command Processing at Scale

Built a webhook that:

  • Receives inbound SMS from twilio
  • Geo-locates the user's phone number (stored in subscriptions table)
  • Fetches their latest forecast in real-time
  • Sends a 160-char SMS reply within 2 seconds
  • Deduplicates to prevent spam

All in < 500ms. We demoed this live β€” texted "WEATHER", got a forecast SMS back in 10 seconds.


πŸ€– 4. AI Risk Scoring That's Explainable

Judges ask: "How do you know it's going to flood?" We can say:

  • "Precipitation in the last 6 hours was 45mm (threshold is 30). Wind is 62 kph (threshold is 50). Soil moisture is high. That's a score of 0.78 = HIGH risk."

We can show the calculation. This is better than a black-box model.


🎨 5. Polish with shadcn/ui

The web dashboard doesn't look like a hackathon project. It looks professional:

  • Proper colour contrast (WCAG AA)
  • Consistent spacing (Tailwind grid)
  • Smooth animations (framer-motion)
  • Dark mode included
  • Responsive design (mobile-first)

shadcn/ui out-of-the-box gives us 90% of the way there.


πŸ“Š 6. Live Responder Coordination

Built real-time WebSocket sync so responders see alert status changes instantly. When one responder marks an alert "resolved", it disappears from all dashboards in < 100ms. This is critical for emergency response β€” no stale data.


What We Learned

1. Contracts > Code

Spending 30 minutes on the API contract (request/response shapes, field names, status codes) saved us 6 hours at Hour 12. If it's not agreed, it breaks.

2. Offline First isn't "nice to have" β€” it's survival

In rural areas, connectivity is intermittent. An app that only works online is useless. Offline-first design forces you to think about:

  • What data MUST be cached?
  • When do we sync?
  • How do we handle conflicts?

This made our app dramatically more resilient even for online users.

3. SMS is a superpower

We thought SMS was "legacy." Wrong. SMS reaches 1 billion people who have no data connection. It's the most robust emergency channel we've got. Africa's Talking's API is incredible (pay $0.05 per SMS in Kenya).

4. Rule-based beats broken ML

We could have spent 30 hours building a fancy ensemble model. Instead, we shipped a simple rule-based scorer at Hour 3 and upgraded to XGBoost if time allowed. The rule-based system is:

  • Faster (no model inference latency)
  • Explainable (users understand why the alert fired)
  • Debuggable (easy to tweak thresholds)

Don't optimize for elegance; optimize for shipping.

5. shadcn/ui is a secret weapon for UX

Spending time on pixels matters in a hackathon. shadcn gives you:

  • Pre-built, accessible components
  • Tailwind theming built-in
  • Dark mode for free
  • Consistent design system

We spent maybe 10 hours on UI instead of 40. That time went to backend reliability instead.

6. Geospatial queries are underrated

PostgreSQL + PostGIS let us answer queries like "all alerts within 50km of lat/lon" in < 10ms. This is non-obvious but critical for a location-based app.


What's Next for SafeSkies

Short term (Weeks 1–4 post-hackathon)

  1. PostgreSQL migration β€” swap SQLite for proper PostGIS geospatial queries
  2. XGBoost trained on production data β€” iterate on the rule-based model with real historical data
  3. Authentication layer β€” users save preferences, emergency contacts, household info
  4. Multi-zone subscriptions β€” "Alert me for both my home in Nairobi AND my farm in Kisii"
  5. USSD gateway (optional) β€” dial *XXX# to get alerts (works on ultra-basic phones)

Medium term (Months 2–6)

  1. Government integration β€” API access for national meteorological services (Kenya Met, NOAA, etc.)
  2. Community volunteer network β€” local field workers validate reports and coordinate response
  3. 7-day forecast model β€” predict risk 1 week ahead; help communities plan (markets, travel, agriculture)
  4. Multi-language support β€” not just UI, but SMS in 10+ languages (Kiswahili, Amharic, Bengali, Tagalog, etc.)
  5. Evacuation routing β€” integrate real-time road closures + safe routes

Long term (6+ months)

  1. Predictive insurance β€” integrate with microinsurance providers; automatic payout if alert triggers
  2. Agricultural advisory β€” seasonal crop recommendations based on weather forecast
  3. Climate resilience training β€” in-app video tutorials on flood prep, cyclone safety, heat stress
  4. Blockchain-based data marketplace β€” communities sell anonymized weather + hazard data to researchers
  5. Expansion to all of Africa β€” replicate the model in 50+ countries

Deployment & Running Locally

Prerequisites

  • Flutter 3.13+ (for mobile)
  • Node.js 18+ (for web)
  • Python 3.10+ (for backend)
  • PostgreSQL 14+ or SQLite (for data)
  • Firebase account (for FCM)
  • Africa's Talking account (for SMS)

Backend

cd safeskies-backend
python -m venv venv
source venv/bin/activate  # on Windows: venv\Scripts\activate
pip install -r requirements.txt
export DATABASE_URL="sqlite:///safeskies.db"
export AFRICAS_TALKING_KEY="your_key_here"
export FCM_SERVER_KEY="your_key_here"
python -m uvicorn app.main:app --reload
# API runs on http://localhost:8000

Web Dashboard

cd safeskies-web
npm install
npm run dev
# Dashboard runs on http://localhost:3000

Flutter App

cd safeskies-flutter
flutter pub get
flutter run -d android  # or -d ios
# Ensure API_BASE_URL in lib/services/api_service.dart points to http://localhost:8000/v1

Production Deployment

  • Backend: git push to Railway; auto-deploys from GitHub
  • Web: git push to Vercel; auto-deploys from GitHub
  • Flutter: Build APK with flutter build apk --release; upload to Google Play or distribute as .apk file

API Reference

Base URL

https://api.safeskies.app/v1

Weather forecast

GET /v1/forecast?lat=-1.286&lon=36.817

{
  "location": { "name": "Nairobi", "lat": -1.286, "lon": 36.817 },
  "current": {
    "temp_c": 22.4,
    "precip_mm": 8.1,
    "wind_kph": 34,
    "humidity_pct": 81
  },
  "risk": {
    "score": 0.74,
    "label": "HIGH",
    "hazard": "flood",
    "message": "Flash flood risk in your area. Avoid low-lying roads.",
    "message_sw": "Hatari ya mafuriko..."
  },
  "alert_active": true,
  "forecast_24h": [...]
}

Active alerts

GET /v1/alerts/active?lat=-1.286&lon=36.817&radius_km=50

Submit hazard report

POST /v1/reports
{
  "lat": -1.295,
  "lon": 36.820,
  "type": "flood",
  "severity": "MEDIUM",
  "description": "Road under 30cm water"
}

See full API docs for complete reference.


Contributing

We'd love your help! Open an issue or PR for:

  • Bug fixes
  • New hazard types (earthquakes, landslides, etc.)
  • Language translations
  • Regional data improvements

See CONTRIBUTING.md for details.


License

MIT License β€” use SafeSkies freely for academic, non-profit, and commercial projects.


Acknowledgments

  • UN Office for Disaster Risk Reduction β€” inspiration for SDG 13 & 11 alignment
  • Open-Meteo β€” free, open weather API
  • NASA FIRMS β€” satellite fire/flood data
  • Africa's Talking β€” SMS infrastructure
  • shadcn/ui β€” design system
  • Flutter & React teams β€” incredible frameworks

Built with ❀️ for WeatherWise Hack 2026

Questions? Email us at contact@safeskies.app or open an issue on GitHub.

Built With

Share this project:

Updates