airnow is an R package for querying and retrieving air quality information from AirNow via the AirNow API. Current and historical readings as well as forecasts can be retrieved as tidy data frames.
You can install the stable version of airnow from CRAN:
install.packages("airnow")If you’d like to try out the development version of airnow, you can install directly from GitHub:
# install.packages("remotes")
remotes::install_github("briandconnelly/airnow")The AirNow API is generally
free to use. The set_airnow_key() function can be used to
help you create and configure your API key.
library(airnow)
set_airnow_key()The AirNow API allows you to query air conditions either by ZIP code or latitude/longitude. Here, we’ll get the current conditions in Seattle by ZIP code:
library(airnow)
get_airnow_observations(zip = "98101")
#> # A tibble: 3 × 21
#> date_observed hour_observed local_time_zone utc_datetime reporting_area
#> <date> <int> <chr> <dttm> <chr>
#> 1 2026-09-12 14 PDT 2026-09-12 21:00:00 Seattle-Belle…
#> 2 2026-09-12 14 PDT 2026-09-12 21:00:00 Seattle-Belle…
#> 3 2026-09-12 14 PDT 2026-09-12 21:00:00 Seattle-Belle…
#> # ℹ 16 more variables: reporting_area_code <chr>, reporting_area_agency <chr>,
#> # state_code <chr>, latitude <dbl>, longitude <dbl>, site_id <chr>,
#> # site_name <chr>, reporting_agency <chr>, parameter <fct>, aqi <int>,
#> # category_number <int>, category_name <ord>, lookup_behavior <chr>,
#> # considered_monitors <chr>, lookup_boundary <chr>, source <fct>Every location belongs to an AirNow reporting area. The
bundled airnow_areas table lists them, and
get_airnow_reporting_area() finds the one for a ZIP code or
coordinate pair.
get_airnow_reporting_area(zip = "94558")
#> # A tibble: 1 × 5
#> reporting_area_code reporting_area state_code latitude longitude
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 ca064 Napa CA 38.3 -122.
get_airnow_forecasts(area = "ca064")
#> # A tibble: 6 × 14
#> date_issue date_valid reporting_area reporting_area_code state_code latitude
#> <date> <date> <chr> <chr> <chr> <dbl>
#> 1 2026-09-12 2026-09-12 Napa ca064 CA 38.3
#> 2 2026-09-12 2026-09-13 Napa ca064 CA 38.3
#> 3 2026-09-12 2026-09-14 Napa ca064 CA 38.3
#> 4 2026-09-12 2026-09-15 Napa ca064 CA 38.3
#> 5 2026-09-12 2026-09-16 Napa ca064 CA 38.3
#> 6 2026-09-12 2026-09-17 Napa ca064 CA 38.3
#> # ℹ 8 more variables: longitude <dbl>, parameter <fct>, aqi <int>,
#> # category_number <int>, category_name <ord>, action_day <lgl>,
#> # discussion <chr>, forecast_agency <chr>library(airnow)
library(dplyr)
get_airnow_monitors(
box = c(-125.394211, 45.295897, -116.736984, 49.172497),
verbose = TRUE
) |>
slice_max(order_by = aqi, n = 1) |>
select(site_name, site_agency, latitude, longitude, aqi, datetime_observed)
#> # A tibble: 1 × 6
#> site_name site_agency latitude longitude aqi datetime_observed
#> <fct> <fct> <dbl> <dbl> <int> <dttm>
#> 1 Troy Idaho Department of En… 46.7 -117. 67 2026-09-12 20:00:00This package and its author are not affiliated with AirNow or its partners. See the Data Exchange Guidelines for more details about this data set and how it should be used. Data are typically refreshed once per hour. Please be kind to this service and limit your request rate.