georest.usgs.wqp¶
Client for the Water Quality Portal (WQP), run by the USGS and EPA.
The largest public store of US water-quality data: samples and field measurements from the USGS, EPA, states, tribes and hundreds of other organizations, at more than a million sites:
from georest.usgs import wqp
sites = wqp.find_sites(state="CO", county="069", site_type="Stream")
temps = wqp.get_results(sites=["USGS-09380000"], characteristic="Temperature, water",
start="2025-01-01", end="2025-12-31")
temps[["date", "value", "unit", "Result_MeasureStatusIdentifier"]]
This client reads the portal’s WQX 3.0 format. The portal’s original format stopped receiving USGS data in 2024: a 2025 search for USGS results that returns 130 rows in WQX 3.0 returns none in the original (checked 2026-10-28). WQX 3.0 queries are slower, often most of a minute.
Results are pandas DataFrames with every column the portal sends, plus
lon and lat (standardized to NAD83) and, for results, date,
value (the measurement as a number) and unit.
Copyright 2026 Ryan Rock and Ian Housman
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Module Attributes
WQX 3.0 queries routinely take most of a minute; allow five. |
|
State postal codes onto FIPS codes, which the portal's state and county filters use ( |
Functions
|
Monitoring locations in the Water Quality Portal. |
|
Water-quality results: samples and field measurements. |
- georest.usgs.wqp.TIMEOUT = 300¶
WQX 3.0 queries routinely take most of a minute; allow five.
- georest.usgs.wqp.STATE_FIPS = {'AK': '02', 'AL': '01', 'AR': '05', 'AS': '60', 'AZ': '04', 'CA': '06', 'CO': '08', 'CT': '09', 'DC': '11', 'DE': '10', 'FL': '12', 'GA': '13', 'GU': '66', 'HI': '15', 'IA': '19', 'ID': '16', 'IL': '17', 'IN': '18', 'KS': '20', 'KY': '21', 'LA': '22', 'MA': '25', 'MD': '24', 'ME': '23', 'MI': '26', 'MN': '27', 'MO': '29', 'MP': '69', 'MS': '28', 'MT': '30', 'NC': '37', 'ND': '38', 'NE': '31', 'NH': '33', 'NJ': '34', 'NM': '35', 'NV': '32', 'NY': '36', 'OH': '39', 'OK': '40', 'OR': '41', 'PA': '42', 'PR': '72', 'RI': '44', 'SC': '45', 'SD': '46', 'TN': '47', 'TX': '48', 'UT': '49', 'VA': '51', 'VI': '78', 'VT': '50', 'WA': '53', 'WI': '55', 'WV': '54', 'WY': '56'}¶
State postal codes onto FIPS codes, which the portal’s state and county filters use (
US:08for Colorado).
- georest.usgs.wqp.find_sites(*, sites: str | Iterable[str] | None = None, state: str | None = None, county: str | None = None, bbox: tuple | None = None, huc: str | None = None, site_type: str | Iterable[str] | None = None, characteristic: str | Iterable[str] | None = None, providers: str | Iterable[str] | None = None) Any[source]¶
Monitoring locations in the Water Quality Portal.
- Parameters:
sites – Site ids, e.g.
"USGS-09380000".state – A state postal code (
"CO") or FIPS code ("08").county – A county’s 3-digit FIPS code, with
state.bbox –
(west, south, east, north)in decimal degrees.huc – A hydrologic unit code (2 to 12 digits).
site_type – e.g.
"Stream","Lake, Reservoir, Impoundment","Well","Spring".characteristic – Keep only sites with samples of this, e.g.
"Nitrate"or"Temperature, water".providers –
"NWIS"(USGS),"STORET"(EPA and partners), or both.
- Returns:
pandas.DataFrame, one row per site, with every WQX 3.0 location column (Location_Identifier,Location_Name,Location_Type, HUC codes, drainage area, …) pluslonandlat.
Example:
from georest.usgs import wqp # Stream sites in Larimer County, Colorado, that measured nitrate sites = wqp.find_sites(state="CO", county="069", site_type="Stream", characteristic="Nitrate") sites[["Location_Identifier", "Location_Name", "Org_FormalName", "lon", "lat"]]
- georest.usgs.wqp.get_results(*, sites: str | Iterable[str] | None = None, state: str | None = None, county: str | None = None, bbox: tuple | None = None, huc: str | None = None, site_type: str | Iterable[str] | None = None, characteristic: str | Iterable[str] | None = None, providers: str | Iterable[str] | None = None, start: str | None = None, end: str | None = None, profile: str = 'basicPhysChem') Any[source]¶
Water-quality results: samples and field measurements.
- Parameters:
sites – Where to look, as for
find_sites(). At least one place is required.state – Where to look, as for
find_sites(). At least one place is required.county – Where to look, as for
find_sites(). At least one place is required.bbox – Where to look, as for
find_sites(). At least one place is required.huc – Where to look, as for
find_sites(). At least one place is required.site_type – Where to look, as for
find_sites(). At least one place is required.providers – Where to look, as for
find_sites(). At least one place is required.characteristic – What was measured, e.g.
"Temperature, water","Nitrate","pH","Escherichia coli".start – Sample dates,
"YYYY-MM-DD".end – Sample dates,
"YYYY-MM-DD".profile – The portal’s column set:
"basicPhysChem"(the default) or"fullPhysChem"for every lab and method detail.
- Returns:
pandas.DataFrame, one row per result, with every WQX 3.0 column (site, activity, characteristic, measure and unit, status, detection limits, method, …) pluslon,lat,date,value(the measurement as a number, empty where the portal reports none, such as a non-detect; seeResult_ResultDetectionCondition) andunit.
Example:
from georest.usgs import wqp temps = wqp.get_results(sites="USGS-09380000", characteristic="Temperature, water", start="2025-01-01", end="2025-12-31") temps[["date", "value", "unit", "Result_MeasureStatusIdentifier"]]