API Reference

Query public pollen, species, forecast, map, weather, and air-quality data. All data endpoints are read-only JSON.

Authentication and browser access

API version 2.2.1 endpoints are publicly readable, require no API key, and allow cross-origin browser requests. Successful data responses use a five-minute shared cache with stale-while-revalidate.

Use the interactive Swagger UI to inspect complete response examples and run safe GET requests.

Quickstart example

curl

curl --fail --silent --show-error \
  'https://pollenmonitor.dev/api/pollen?city=berkeley&date=2026-08-25'

JavaScript

const response = await fetch(
  'https://pollenmonitor.dev/api/pollen?city=berkeley&date=2026-08-25'
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();

Python

import requests

response = requests.get(
    'https://pollenmonitor.dev/api/pollen?city=berkeley&date=2026-08-25',
    timeout=15,
)
response.raise_for_status()
data = response.json()

A successful response has this shape. The OpenAPI contract includes equivalent curl, JavaScript, and Python samples for every operation.

{
  "city": "berkeley",
  "date": "2026-08-25",
  "rows": [
    {
      "ts": "2026-08-25T18:00:00.000Z",
      "tree": 20,
      "grass": 4,
      "weed": 29,
      "total": 53,
      "species": {
        "Tree": {
          "Elm": 20,
          "Oak": 0
        },
        "Grass": {
          "Grass": 4
        },
        "Weed": {
          "Ragweed": 29
        }
      },
      "risk_tree": "Moderate",
      "risk_grass": "Low",
      "risk_weed": "Moderate",
      "timezone": "America/Los_Angeles"
    }
  ]
}

Available dates

GET https://pollenmonitor.dev/api/available-dates
GET https://pollenmonitor.dev/api/latest-date

Discover all UTC dates with observations or retrieve only the latest observation date.

Units and risk methodology

Values are modeled Ambee pollen concentrations in grains/m³. Risk labels use category-specific National Allergy Bureau (NAB) ranges: Weed/Ragweed 10, 50, 500; Grass 5, 20, 200; Tree 15, 90, 1500. Zero is None, and multi-species categories are graded by the highest individual allergen rather than the category sum.

Cities

GET https://pollenmonitor.dev/api/cities

Returns an alphabetised list of supported cities with both display names and URL-safe slugs.

Hourly readings

GET https://pollenmonitor.dev/api/pollen?city=san-francisco&date=2024-04-14

Provide both city and date (UTC) to retrieve all hourly observations for that day, including per-species values and NAB category risk labels.

Daily averages

GET https://pollenmonitor.dev/api/pollen?city=san-francisco

Omit the date parameter to receive up to 720 daily averages for a city, including per-species averages rounded to whole numbers.

Cross-city map data

GET https://pollenmonitor.dev/api/map-data?date=latest

Compact GeoJSON with one point per city, daily category and Ragweed maxima, NAB risks, coordinates, timezone, and a three-day series. The response includes aggregation: daily-category-maxima; full species blobs are omitted to keep cross-city responses small.

48-hour forecast

GET https://pollenmonitor.dev/api/forecast?city=denver

Hourly pollen forecast for the next 48 hours (Ambee), including species when supplied by the provider. Responses are cached server-side for up to 6 hours per city. If an upstream refresh fails, the most recent cached rows are returned with stale: true. When the daily provider quota blocks a refresh, the response also includes quotaExhausted: true.

Daily weather

GET https://pollenmonitor.dev/api/weather?city=denver&date=2026-07-08

Daily weather and air-quality observations (OpenWeather) collected alongside pollen data. Provide city, date, or both: city alone returns up to 365 days (newest first), date alone returns a compact per-city snapshot for that day. Measurements unavailable from the provider are omitted rather than returned as null.

Custom ranges

GET https://pollenmonitor.dev/api/pollen-range?from=2024-04-01&to=2024-04-15&city=denver&aggregate=day

Use /api/pollen-range for arbitrary windows. Supply from and to, optionally filter by city, and set aggregate=day for daily summaries. Hourly and daily modes return the same flat row shape.

Parameters: from (required), to (required), city (comma-separated slugs), aggregate (strictly none or day; unknown values return 400), limit (integer from 1–50 000, defaults to 20 000; invalid values return 400).