USGS Water Services

Government API · United States · Streamflow and water data

TL;DR

The USGS Water Services API delivers real-time and historical water data from over 1.5 million monitoring sites across the United States. Access streamflow/discharge rates, groundwater levels, surface water stage (height), water temperature, specific conductance, dissolved oxygen, pH, turbidity, and precipitation. Query by site number, state, county, or geographic bounding box. Data goes back decades for many sites. The authoritative source for US water information — used for flood forecasting, drought monitoring, water resource management, and environmental research.

Quick start: https://waterservices.usgs.gov/nwis/iv/?site=03339000&format=json

No API key needed — just make a request!

Streamflow data for site 03339000: https://waterservices.usgs.gov/nwis/iv/?site=03339000&format=json

How to Use This API

1. Real-Time Data for a Site

https://waterservices.usgs.gov/nwis/iv/?site=03339000&format=json

2. Sites by State (Recent Data)

https://waterservices.usgs.gov/nwis/iv/?stateCd=ca&format=json

3. Historical Daily Data

https://waterservices.usgs.gov/nwis/dv/?site=03339000&format=json&startDt=2025-01-01&endDt=2025-12-31

4. Site Search by County

https://waterservices.usgs.gov/nwis/site/?stateCd=ny&countyCd=081&format=json

5. JavaScript — River Level Check

async function riverLevel(siteId) {
  const resp = await fetch(
    `https://waterservices.usgs.gov/nwis/iv/?site=${siteId}&format=json`
  );
  const data = await resp.json();
  const ts = data.value.timeSeries[0];
  
  const name = ts.sourceInfo.siteName;
  const value = ts.values[0].value[0].value;
  const unit = ts.variable.unit.unitCode;
  const time = ts.values[0].value[0].dateTime;
  
  console.log(`Site: ${name}`);
  console.log(`Value: ${value} ${unit}`);
  console.log(`Time: ${time}`);
}

riverLevel('03339000'); // Vermilion River near Danville, IL

6. Python — Flood Monitoring

import requests

def check_flood_sites(state='tx'):
    resp = requests.get(
        'https://waterservices.usgs.gov/nwis/iv/',
        params={
            'stateCd': state,
            'format': 'json',
            'parameterCd': '00065'  # Gage height
        }
    )
    data = resp.json()
    
    print(f'Sites with gage height data in {state.upper()}:')
    for ts in data.get('value', {}).get('timeSeries', [])[:10]:
        site = ts['sourceInfo']['siteName']
        val = ts['values'][0]['value'][0]
        height = val['value']
        time = val['dateTime'][:16]
        print(f'  {site}: {height} ft at {time}')

check_flood_sites('la')

Frequently Asked Questions

What parameters are measured?
Streamflow (discharge), gage height (stage), groundwater levels, water temperature, specific conductance, dissolved oxygen, pH, turbidity, and precipitation. Each parameter has a 5-digit code.
Do I need an API key?
No. USGS data is public domain — no authentication required.
How do I find site IDs?
Search by state using stateCd or use the USGS National Water Information System (NWIS) mapper to find monitoring sites by location.
What's the difference between IV and DV?
IV (Instantaneous Values) — real-time data typically recorded every 15 minutes. DV (Daily Values) — daily averages calculated from instantaneous readings.
How far back does historical data go?
Many sites have data going back to the early 1900s. Use startDt and endDt parameters in YYYY-MM-DD format.
What area is covered?
The entire United States including Alaska, Hawaii, and US territories. Over 1.5 million sites monitored by USGS in cooperation with state and local agencies.

API Details

API URL
https://waterservices.usgs.gov/nwis/
Documentation
waterservices.usgs.gov
Category
Government
Authentication
Not Required
Geographic Coverage
United States and territories

What You Can Build