Haze Monitor

August 2026 to present · Co-built with Isaac Tan · Search, AI answers and design

A glass dome over a hazy miniature Kuala Lumpur skyline, on a worn blue base with an AQI dial

I started Haze Monitor at the end of August 2026, just before haze season, and built it with Isaac Tan. It reads DOE Malaysia's live station feed and Singapore's NEA readings, then shows the nearest reading over an illustrated picture of your city. The haze in the picture thickens with the number. It is free and has no ads.

From October 2 to 29, 18K people used it. Bing sent 5.3K first-time visitors, more than Google's 3.9K, and ChatGPT sent 2.7K. This page is about the search and AI-answer work behind those numbers.

Pages that answer in the HTML

The first version fetched every reading in the browser. A crawler got a page title, a heading and a dash where the number should be. Isaac fixed that first. He moved the readings to the server so the number arrives in the HTML, then added a short summary under each city in English and Malay. Malaysians search in both languages, with words like 'jerebu', 'IPU' and 'indeks pencemaran udara'.

He also gave every place its own page. Fourteen city pages had left most of the country with nothing to land on, so he added one for each of the 68 DOE stations and 16 states. The URLs use the names people type, so Penang is /state/penang, not pulau-pinang. The sitemap grew from 17 URLs to 101. It has 272 now.

My part was matching each page to the words people use. Malaysia's official index is called API, the Air Pollutant Index. Searchers also type AQI. We calculate a US AQI from DOE's PM2.5 readings, show it next to the official API, and put both terms in the titles, as in 'Malaysia AQI & Haze Today (API/IPU)'. The Malaysia and Singapore reports also have Malay and Simplified Chinese versions linked with hreflang. The Chinese Malaysia report is one of the three most-viewed pages on the site.

Haze Monitor's Kuala Lumpur view with a US AQI of 101 over an illustration of the Petronas Towers
The Kuala Lumpur page on November 1. The reading, its station and its age sit over the city artwork, and the haze in the picture follows the number.
what people searchwhat Haze Monitor answers with
jerebu hari ini
A Malay summary on every city pageWith API/IPU facts and DOE health guidance
Malaysia AQI
US AQI next to the official APICalculated from DOE PM2.5, with the method shown
马来西亚 烟霾
A Simplified Chinese country reportLinked to the English and Malay versions with hreflang
air quality Petaling Jaya
A page for every station, city and state68 stations and 16 states, named the way people type them
Singapore PSI today
A Singapore report with PSI and PM2.5Five regions, each with its own observation time
haze last week
Weekly reportsFive countries, with archives by ISO week
Most of the ranking work was matching pages to the words people already use.

Making it easy for AI assistants to quote

I wanted ChatGPT to cite Haze Monitor when someone asked it about the haze. I ran the site through is-agentic.com, which scores how well AI agents can read and use a website, and worked through what it flagged.

Every public page now returns clean Markdown when a client sends Accept: text/markdown, and has a matching .md URL. llms.txt tells an assistant which page answers which question and how to read the numbers. It explains that Malaysia's API is not the US AQI and that every reading has an observation time to check. Missing pages return a real 404 with links back. An OpenAPI 3.1 file describes the six public JSON endpoints. They need no key and return errors with a stable code and a hint for recovering.

hazemonitor.com scores 97 out of 100 on is-agentic, with all eight essential checks passing. In four weeks ChatGPT sent 2.7K first-time visitors, more than Yahoo and DuckDuckGo combined. Bing surprised me more. The only search tool I used was Google Search Console, to submit the sitemap. Bing found the site on its own and still sent more first visits than Google.

Google Analytics for hazemonitor.com from October 2 to 29, 2026, showing 18K active users and Bing as the top first-user source
Google Analytics, October 2 to 29. Bing is the top source of first visits, and chatgpt.com is fourth.

How a question reaches a reading

01Someone asks

They search 'jerebu KL' or ask ChatGPT about the haze.

02A page matches

Every station, city and state has its own URL in the sitemap.

03The HTML answers

The reading, category and time are rendered on the server.

04Assistants get Markdown

llms.txt and Accept: text/markdown give them a clean copy to quote.

05The page stays fresh

Pages rebuild every five minutes from DOE and NEA.

Crawlers and assistants get the reading without running any JavaScript.
Read it like an assistantterminal
# The Malaysia report as Markdown
curl -H 'Accept: text/markdown' https://hazemonitor.com/malaysia

# Which page answers which question
curl https://hazemonitor.com/llms.txt

# Six read-only JSON endpoints, no key needed
curl https://hazemonitor.com/openapi.json

curl -H 'Accept: text/markdown' https://hazemonitor.com/malaysia

Every public page has a Markdown version, and llms.txt points assistants to the right one.

Numbers people can trust

A haze site that shows the wrong number is worse than none. Every reading keeps its station name and observation time. If a station stops reporting, the page keeps its last reading and labels it as old. It never borrows a reading from a station farther away. A D1 archive on Cloudflare fills gaps when the DOE or NEA feed fails, and it keeps the original timestamps.

The AQI conversion needed the most care. On September 21 I found we were still using DOE's 2021 PM2.5 formula. For Cheras, it turned an official API of 139 into a US AQI of 185. The current formula gives 147, which matches DOE's own 24-hour PM2.5 figure. I checked the corrected table against all 67 stations that report both values, and every one agreed within one index point.

Weekly reports give people and search engines something new each week. Malaysia, Singapore, Thailand, Indonesia and Vietnam each have one, with archives by ISO week. The Thailand, Indonesia and Vietnam reports use CAMS model estimates. They are labelled as estimates and never enter the archive of measured readings.

The Haze Monitor Malaysia weekly report for October 21 to 27, 2026, with a weekly mean US AQI of 94.1
The Malaysia weekly report for October 21 to 27, built from 11,303 hourly observations.

Where the numbers come from

Sources
DOE Malaysia68 stations, hourly API and PM2.5
NEA SingaporePSI and PM2.5 for five regions
Open-Meteo CAMSModel estimates for Thailand, Indonesia and Vietnam
Store
Collector WorkerSaves readings on a schedule
D1 archiveFills gaps and keeps original timestamps
Serve
Cloudflare WorkerPages rebuilt every five minutes
Public APISix read-only JSON endpoints with OpenAPI 3.1
Read
PeopleIllustrated city pages
Search enginesServer-rendered HTML and a 272-URL sitemap
AI assistantsllms.txt and Markdown versions
When a feed fails, the archive supplies the last known reading with its original time.