AWS Builder Center
Building Saans: a personal air-quality companion for India on AWS serverless

Building Saans: a personal air-quality companion for India on AWS serverless

How we built Saans for the AWS × WeMakeDevs hackathon: an English and Hindi air-quality app that gives each person advice for their own exposures, finds cleaner routes using live monitors, and lets officials send advisories. Built on AWS Lambda, Step Functions, SNS, Amazon Location Service and Amplify Hosting.

Every winter, north India's air turns grey. People in Delhi check an app, see "AQI 300, Very Poor", and then still have to decide everything themselves. Should I let my child walk to school? Is my commute making it worse? Does any of this matter if I cook on a wood stove at home?
One number cannot answer those questions, because the risk is personal. A construction worker outside for eight hours, a pregnant woman cooking on kerosene, an asthmatic teenager and an office worker in a car all breathe the same city, but not the same dose.
For the AWS × WeMakeDevs hackathon we built Saans (Hindi for "breath"), an installable web app that turns live air data into personal, practical decisions, in English and Hindi.

What Saans does

It starts with you. A six-step onboarding asks about age and pregnancy, work and hours outdoors, your home (floor, a main road or construction nearby, cooking fuel, smoking indoors, a purifier) and health conditions like asthma, COPD or heart disease. Saans derives a persona from those answers, and the answers stay on the device.
Today shows the air where you are: PM2.5, PM10, NO2, O3, CO and SO2, an indicative AQI computed with the CPCB method, and alerts written for your persona.
Ask Saans answers questions in English or Hindi from the same live data. We rank each person's own exposures first. For someone whose family smokes indoors and cooks on wood, the assistant opens with that, because it outweighs any outdoor advice, and then covers the rest.
Trip planner compares up to three driving routes. It samples PM2.5 and visibility every ~2 km, blends in live monitors near the road, flags fires within 10 km, and charts the cleanest hour to leave over the next 24 hours.
Health shows an animated lung for each pollutant: where it deposits, what it does in the short and long term, and how many times over the WHO 2021 guideline today's level is.
Government view gives officials an Area watch (NASA FIRMS fire hotspots, the 500 km upwind zone from the current wind, mixing height and ventilation index) and a one-click advisory. The advisory is generated in Hindi and English from live data and goes to every subscriber within 5 km.

Architecture

Everything runs in ap-south-1 (Mumbai) and is defined in a single AWS SAM template.
  • AWS Amplify Hosting serves the PWA over HTTPS.
  • Amazon API Gateway (HTTP API) fronts a Node.js 22 AWS Lambda function that does the data work.
  • Amazon DynamoDB caches upstream responses and stores alert subscribers.
  • Amazon Location Service powers place search.
  • Amazon SNS, AWS Step Functions and Amazon EventBridge Scheduler deliver hourly alerts and advisories.
  • AWS Systems Manager Parameter Store holds every third-party key as a SecureString.
  • Amazon Bedrock is the assistant's first-choice model.
  • AWS X-Ray, Amazon CloudWatch and AWS CloudTrail give us tracing, metrics and an audit trail.
The data comes from open sources: OpenAQ for ground monitors, Open-Meteo for the CAMS air-quality forecast and ERA5 weather, NASA FIRMS for satellite fire detections, and OSRM for routes.

Five things we learned building it

1. Shortest is not the same as cleanest

Our first trip planner scored routes on the CAMS forecast alone. CAMS works on a grid of roughly 40 km, so two routes across Delhi usually landed in the same cells and got the same concentration. The shorter route then always "won" on exposure, and the app called it the least polluted, which was really just a statement about distance.
We fixed that in two ways. First, the planner now reads live OpenAQ monitors along each route: one bounding-box query lists the monitors, we keep those that reported in the last 3 hours and sit within 6 km of the road, and each sample is rescaled to the inverse-distance-weighted monitor reading. Each route card says how many monitors it used and how much of the road they cover. Second, when the routes' average PM2.5 is within a small margin, Saans says plainly that they breathe the same air and the quicker one gives the lower dose. Being honest about uncertainty mattered more to us than always picking a winner.

2. Rate limits shape the design

OpenAQ allows 60 requests a minute on one key, which is shared by every user. Our first version fetched each nearby station separately per route and hit HTTP 429 within a few searches. The redesign uses one bounding-box listing per trip (cached for an hour), at most 15 monitor readings (each cached 15 minutes), and DynamoDB caching of whole responses for 5 minutes. A response with a provider outage is cached for only 60 seconds, so a blip does not stick.

3. Exact place search changed how people use it

People don't think in coordinates or city names. They think "DTU", "Rohini Sector 18" or "the Saket metro". Amazon Location Service's SearchText, biased to the user's position and filtered to India, finds those directly. It needed one IAM statement and a few lines of code, with Open-Meteo geocoding as a fallback.

4. Reliable alerts need per-subscriber isolation

Hourly alerts run as a Step Functions state machine triggered by EventBridge Scheduler at five past every hour, in the Asia/Kolkata time zone. A Map state alerts subscribers three at a time with retries, and catches failures per subscriber, so one bad address never blocks everyone else. It stays quiet from 10 pm to 7 am unless the air turns very poor. SNS filter policies let one topic deliver a different message to each subscriber.

5. AI should fail safe, and fall back

The assistant tries Amazon Bedrock first, then Google Gemini, then deterministic rule-based answers built from the same data and CPCB guidance. Every response says which one answered. We also tried a small self-hosted model on a SageMaker serverless endpoint and dropped it: the 1.5B model was too slow on CPU for the API timeout, and the 0.5B model gave unsafe health advice. For a health app, a calm rule-based answer is better than a fluent wrong one.

Being honest about the data

Air-quality apps often blur model output and real measurements. Saans keeps them apart. Monitor readings and the CAMS forecast are labelled separately. The AQI is called indicative, because the official CPCB AQI uses certified monitor data. The estimate range is described as a spread of nearby monitors, not as a confidence interval. The health content is general WHO and EPA guidance, not medical advice.

Deploying it

The whole backend is one  sam deploy . We first tried to put the website on S3 behind Amazon CloudFront, but our new account needed verification before it could create CloudFront distributions, and the stack rolled back cleanly. We moved the site to AWS Amplify Hosting, which also gives HTTPS and a CDN, with two resources in the same template and a short script that zips the files and starts a manual deployment.

What's next

  • Integrate the official CPCB live feed (via data.gov.in) for many more monitors.
  • Turn on Amazon Bedrock model access, and add Bedrock Guardrails and retrieval over reviewed health guidance.
  • Model smoke transport properly instead of the straight-line upwind wedge.
  • Add a custom domain, more Indian languages and push notifications.
Clean air is a policy problem. But until the air improves, people still have to make choices every day, and Saans is our attempt to make those choices easier and better informed.
Built for the AWS × WeMakeDevs hackathon by team hawa_hawai.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article