
AIRQ: Making Air-Quality Data Something You Can Explore
How we built AIRQ, an air-quality exploration and strategy platform covering 790 Indian districts using environmental data, Python, and AWS. This article explores our data pipeline, serverless architecture, satellite fire detection, pollution-control simulations, and the engineering challenges we encountered along the way.
We noticed a strange problem while building AIRQ: zoom out on the map, and half of India loses its colour. The data was there. The problem was in the animation. MapLibre was recalculating the district layout again and again, every frame. Fixing that bug became a good reminder of what this project really involved: not just a strong idea, but the engineering needed to make it work for real people.
We wanted air quality to feel like more than a number on a screen. With AIRQ, people can explore a district, check its 48-hour forecast, follow wind patterns, investigate possible fire-related sources and try pollution-control choices in a strategy game. We also built ways to submit green actions and register fields for satellite fire checks. The aim is simple: make environmental information easier to explore, and give people a reason to engage with it.
AIRQ covers 790 Indian districts. The values on the map are estimates based on forecast data, not measurements from a monitoring station in every district. We make that distinction visible because useful environmental technology should help people understand the data, including its limits.
From an AQI number to the bigger picture
Choose a district and AIRQ shows its estimated AQI, a 48-hour forecast and an estimated breakdown of possible pollution sources. Wind particles make air movement easier to follow. Open “Trace the Smoke” and the map adds a simplified 36-hour back-trajectory, with satellite fire detections displayed near the route.
The route is a clue to investigate, not proof that a particular fire caused pollution in a district. We use a simplified transport calculation, so the feature helps users explore possible connections without claiming certainty the data cannot provide.
In Defend mode, every decision has a cost. You start with four points and choose interventions such as crop-residue management, dust control and industrial fuel changes. Each option affects different estimated source shares, and the resulting scenario appears over the forecast. Users can compare their choices before spending the whole budget.
A smog tower is a useful example. Under the assumptions used in our game, it takes half the budget but reduces the vehicle and dust components by just 0.4%. The district-wide result barely moves. Seeing that trade-off makes the game more than a score screen: it gives people a way to question which interventions may have the greatest reach in a scenario.
These results are game scenarios, not verified predictions of real policy outcomes. We use the same assumptions to compare interventions, their estimated reach and their cost within the game.
The data that brings AIRQ to life
The map is powered by a shared file called world.json. Our Python pipeline combines particulate-matter forecasts from the Copernicus CAMS model, accessed through the Open-Meteo Air Quality API, with Open-Meteo wind and boundary-layer data and NASA FIRMS VIIRS fire detections. The processed snapshot is what the frontend reads, rather than asking every user interaction to fetch all the outside feeds again.
For each district, we calculate a particulate-based AQI estimate using rolling 24-hour PM2.5 and PM10 values and CPCB breakpoint tables, then use the higher of the two subindices. This is not the full official AQI across every pollutant. We also do not train a separate forecasting model; the forecast comes from CAMS.
Source breakdowns require another layer of estimation. We start with literature-based regional priors and adjust them using factors such as nearby coal capacity, overnight mixing and fires along the trajectory. Because these shares are inferred rather than directly measured, AIRQ labels them as estimates and shows low or medium confidence.
AWS runs the update cycle behind the scenes. Every four hours, EventBridge Scheduler starts a Standard Step Functions workflow. Lambda functions gather and process the feeds, save the latest snapshot in private Amazon S3 storage and archive a copy. Separate workflow steps handle registered-field checks, nearby-fire alerts and smog-raid events, with EventBridge and Amazon SNS carrying those events to the relevant functions.

We built the website with React, TypeScript and Vite. MapLibre GL renders the map, and a custom Canvas layer draws the moving wind particles. Amazon CloudFront serves both the frontend and the shared world snapshot. That means opening another district can reuse the same processed data instead of triggering another round of external API requests.
The interactive features have their own backend paths. Amazon API Gateway routes questions and reward claims to separate Lambda functions, while Amazon DynamoDB stores player state, proof records, subscriptions and question quotas. AWS SAM defines the deployment, keeping the infrastructure setup alongside the project code.
AWS: the services behind AIRQ
For us, AWS was not just a place to publish the website. It became the system that connects data collection, processing, delivery, user interactions and AI. Managed services let us focus on the environmental problem while still building a pipeline that can recover from delays and keep the map available.
Our hackathon materials also map the wider AWS ecosystem across seven areas. The distinction matters: some tools are part of the local build workflow, while others are cloud services used after deployment. The list below shows the range of options, not a claim that AIRQ runs every service. The services we actually use in AIRQ are called out in the project flow that follows.
Area | Build and test | Deploy and operate |
|---|---|---|
Agents and AI | Strands Agents SDK, PartyRock | Amazon Bedrock / Nova Micro in AIRQ; SageMaker AI is part of the wider AWS ecosystem |
Containers and Kubernetes | Finch, EKS Distro, EKS Anywhere | EKS, ECS, Fargate |
Serverless | AWS SAM CLI, LocalStack | Lambda, API Gateway, Step Functions |
Servers and runtimes | Firecracker, Corretto | EC2, Lightsail, App Runner, Amplify Hosting |
Data and search | OpenSearch | S3, DynamoDB, RDS, Aurora |
Auth and policy | Cedar | Cognito |
Delivery and operations | No separate build tool listed | CloudFront, Route 53, EventBridge, SQS, SNS, CloudWatch |
Area | Build and test locally | Ship it on AWS |
|---|---|---|
Agents and AI | Strands Agents SDK; PartyRock | Amazon Bedrock with Nova Micro and Nova Lite Used in AIRQSageMaker AI is another AWS option. |
Containers and Kubernetes | Finch; EKS Distro; EKS Anywhere | Amazon EKS; Amazon ECS; AWS Fargate Not used in AIRQ’s current deployment. |
Serverless | AWS SAM CLI; LocalStack | AWS Lambda; API Gateway; Step Functions Used in AIRQ |
Servers and runtimes | Firecracker; Amazon Corretto | Amazon EC2; Lightsail; App Runner; Amplify Hosting Alternative deployment options. |
Data and search | OpenSearch | Amazon S3; DynamoDB Used in AIRQAmazon RDS, Aurora and OpenSearch are other options, not part of this build. |
Auth and policy | Cedar | Amazon Cognito Not used in AIRQ’s current deployment. |
Delivery and operations | Local development and testing tools | Amazon CloudFront; EventBridge; SNS Used in AIRQRoute 53, SQS and CloudWatch are also part of the AWS toolkit; they are not listed as core AIRQ components here. |
AIRQ’s deployed flow is specific: EventBridge Scheduler starts Step Functions, Lambda processes the external feeds, Amazon S3 stores the latest snapshot, and CloudFront delivers it to users. API Gateway routes questions and reward claims to Lambda, DynamoDB stores player and reward records, and Amazon Bedrock powers The General and part of the evidence-review flow. AWS SAM defines the deployment. Each service has a job in the product, rather than being included just to make the architecture look bigger.
Keeping the data flowing
A refresh has a lot to get through. Each run requests air-quality data for 790 district locations and wind data for a 546-point grid. That is 1,336 locations before the fire feeds are included.
External APIs have rate limits, so we send requests in batches and pause between them. If a provider returns a rate-limit response, the pipeline waits and retries. Those waits can add several minutes, so we use a Standard Step Functions workflow that can handle a longer run instead of an Express workflow with a five-minute execution limit.
We also planned for missing data. AIRQ keeps the last successful copy of each feed. If a fresh request fails, the pipeline can use that saved copy and mark it as stale. The interface can then tell users that some feeds are delayed instead of presenting old data as if it were new.
Follow-up jobs are separated from the main refresh. If a field check or alert fails, it should not undo a world-data update that already succeeded. That separation helps keep the map available even when a secondary task needs attention.
The map bug we had to solve
We wanted districts at risk to stand out with a soft haze and a moving dashed border. Our first attempt changed a data-driven paint property on every animation frame. MapLibre kept rebuilding the district layout, and when users zoomed out, large parts of the map stayed uncoloured.
We changed the animation to use constant paint values. MapLibre also could not animate the dash offset the way we needed, so we prepared 14 line layers with different dash phases and switched between them. It took a less obvious approach, but it stopped the repeated layout work and gave us the effect we wanted.

We added a regression script for the zoomed-out colouring bug, along with checks for browser Back and Escape behaviour. We also improved smaller details: touch users should not get stuck with hover tooltips, animations should respect reduced-motion settings, and a district link should open the selected destination without replaying the intro tour.
Meet The General, our AI guide
The General is AIRQ’s AI assistant. It uses the Strands Agents SDK and Amazon Nova Micro through Amazon Bedrock. It can look up a district, rank districts and find nearby fires. When it mentions districts, those locations are highlighted on the map so users can connect the answer with the data in front of them.
We wanted the assistant to help people navigate the data, not make confident-sounding guesses. Its instructions tell it to use tools for factual answers and describe source shares as estimates. Health guidance follows a separate path: application code uses a fixed matrix informed by CPCB statements and GRAP, rather than asking the model to generate health advice on its own.

We added checks for certain medical terms and dosage patterns in the assistant’s output, but we do not treat those checks as a complete safety guarantee.
We first built the advisor around Claude Sonnet 4.5, then switched to Nova Micro to manage cost and use a model available directly through Bedrock. Morning briefings are cached by district and four-hour data tick, and chat is limited to ten questions per hashed IP each day.
The deployment can also be configured with a $15 monthly budget alert. It is a warning threshold, not a promise that the project will cost $15 or a hard spending cap.
Making reward claims harder to abuse
AIRQ awards experience points, but spendable credits need stronger checks. For photo-based claims, a Lambda function decodes and re-encodes the image, removes metadata and checks exact and perceptual hashes against previously approved images. Perceptual hashes can catch some copies that have been resized or saved in a different format.
For higher-value actions, the photo must also show a handwritten one-time code that expires after 15 minutes. Amazon Nova Lite reviews the visible evidence through Bedrock, and the result is checked against the code requirement and the relevant limits.
We also accounted for a less obvious risk: two requests can arrive at nearly the same time. If both pass an early check, the same action could otherwise be paid twice. Conditional writes claim the image hash, and a versioned player update checks the limits again before the reward is issued.

A photo cannot prove every claim. A picture of a bus, for example, cannot prove that someone chose public transport instead of driving. The model can also approve the wrong image or reject a genuine one, so this part of AIRQ still needs more testing.
We flag a small percentage of approvals for later human spot-checking. The review interface is planned, not finished, and we need to measure false approvals and false rejections before relying on the process at a larger scale.
Using satellite data to check registered fields
Registered fields use satellite fire detections rather than photo submissions. Under the current rules, a daily check with no VIIRS fire detection can earn credits; a detected fire starts a cooldown. If checks stop for too long, the streak resets instead of paying for a period we did not observe.
Weekly settlement gives the satellite feed time to catch up before group rewards are finalised. That matters because observations can arrive late, and settling too early could leave out a pass that has not yet appeared in the data.
We deliberately say “no fire detected,” not “no fire happened.” Satellites can miss fires between passes, under cloud cover, or when a fire is too small or cool to detect. That difference is important when environmental data is tied to rewards.
Village Fire Pacts let people participate as a group. Weekly settlement waits until Tuesday to allow for late satellite passes, and conditional writes help prevent duplicate payouts. The public pact map shows a ring only when at least three fields are involved, and rounds its centre to roughly ten-kilometre precision. Individual field pins are not shown in that layer.
There is still work ahead. Physical reward fulfilment is being arranged, and the photo-review interface is unfinished. DigiLocker, e-RUPI, CSR funding and ground-station correction are ideas for the future, not features we are claiming as complete. Some player scans and field jobs will also need to change before AIRQ can support a much larger number of users.
Our next test is simple: put AIRQ in front of people who have never seen the code. Can they tell a forecast from a Defend scenario? Can they submit a genuine action without getting stuck? Watching someone use the platform for the first time will reveal things that logs and calculations cannot.
Try AIRQ by choosing a district, opening “Trace the Smoke” and building a Defend plan to compare its effect on the forecast. The repository includes the data pipeline, AWS SAM deployment, advisor and reward logic. We would love to hear where the experience is clear and where it needs work.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article