US River Water Level API - Official USGS Streamflow Gauges
Pricing
$10.00 / 1,000 gauge reading returneds
US River Water Level API - Official USGS Streamflow Gauges
Live river water level, streamflow and water temperature from official USGS gauges - no API key. Every reading carries its USGS quality codes in plain English, so you can tell an approved measurement from a provisional one, a frozen gauge or a dry channel. -999999 is never returned as a level.
Pricing
$10.00 / 1,000 gauge reading returneds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 hours ago
Last modified
Categories
Share
Live river level, streamflow and water temperature from the government's own gauges - with the three facts you need to know whether a number is usable: how old it is, whether the sensor was working, and whether it will be revised.
This reads USGS Water Services (waterservices.usgs.gov), the official public API of the US Geological Survey. It is a work of the US government: public domain, no API key, no rate-limit contract, no terms that forbid redistribution. Nothing here parses a website. No proxies required.
Why not just call the API yourself
Four traps. Each one turns into a wrong number in your system without anything looking broken. All four were measured on live data across 55 US states and territories, 31,752 time series on 2026-08-30.
1. -999999 is the missing marker - and it is not the only bad number
-999999 appeared in 2.64% of readings. A naive client reports a river at minus 999,999 feet.
But filtering only for that is not enough: real responses also contain values like -100000 and a water temperature of -120 °C. This Actor checks each measurement against a physical range as well, so waterTemperature outside roughly -3 to 70 °C is reported as missing rather than as a reading.
Careful: large negative streamflow is real - it is tidal backflow (Savannah River at Fort Pulaski runs to -218,000 ft³/s). A client that simply discards big negative numbers destroys real data. The range is set per measurement, not per sign.
2. Freshness is a separate question from quality - and it bites hard here
26.6% of live readings across the country are more than a year old. The service returns them with no warning. The oldest gauge in the Arizona sample was last read 13,847 days ago and still comes back in a request for current conditions.
Every measurement therefore carries ...AgeHours, and every row carries freshestAgeHours. If you are monitoring for flooding, filter on those.
A warning worth spelling out. USGS quality code
Ameans "approved for publication". It is tempting to treatAas "trustworthy". Do not. In the instantaneous-value service, approval only happens after review, soAis attached to historical records: of 2,207Areadings measured, 100% were more than 24 hours old and the oldest was 45 years old. Almost every current reading isP(provisional). Filtering for "approved" data leaves you with no current data at all. This Actor therefore does not publish a single "trusted" flag - it gives you age, suspect and provisional separately, and lets you decide.
3. Quality codes decide whether the number means anything
A gauge can be iced over, dry, under maintenance, or broken. ...IsSuspect is true when any code says the measurement itself was affected, and ...QualifierMeanings spells out why in English.
| Code | Meaning | Suspect |
|---|---|---|
A Approved for publication | (see the warning above - approved usually means old) | no |
P Provisional - subject to revision | the normal state of current data | no |
R Revised record | no | |
Dry The channel is dry at this site | no | |
ZFL Zero flow | no | |
e Estimated | yes | |
Ice Value affected by ice at the site | yes | |
Eqp Value affected by equipment malfunction | yes | |
Mnt Site under maintenance | yes | |
Fld Value affected by flood damage | yes | |
Bkw Value affected by backwater | yes | |
Rat Rating being developed or revised | yes | |
Ssn Monitored seasonally - not measured now | yes | |
Dis Record discontinued at this site | yes | |
*** Temporarily unavailable | yes | |
< Actual value is less than the value shown | yes |
Any code not in this list is reported as Unknown USGS qualifier '<code>' and treated as suspect, so a new code can never quietly pass as a clean reading.
4. One gauge can have several sensors, and the API does not put the good one first
USGS returns a separate block per measurement method - Primary, Secondary, Bubbler, Radar, Upper Stage Sensor. Measured nationwide: 720 series carry more than one block, 612 of them disagree on the value, and in 11 the first block is missing while another sensor has a real reading. One gauge reported no water level at all while its radar sensor was reading 11.11 ft.
This Actor picks the freshest block that actually has a reading, and tells you which one it used in ...Sensor.
What you get
One row per gauge site, with the same columns every time - a site that does not measure something gets null, never a zero.
| Field | Example | Notes |
|---|---|---|
siteCode / siteName | 09379025 / CHINLE CREEK AT CHINLE, AZ | As USGS names it |
latitude / longitude | 36.155 / -109.5375 | |
stateFips / countyFips | 04 / 04001 | FIPS numbers, not AZ - named for what they actually are |
timeZone | MST | |
streamflow / gageHeight / waterTemperature + ...Unit | 0 / 2.2 / null | ft³/s, ft, °C |
...AgeHours | 1.6 | How old this measurement is, in hours |
...ObservedAt | 2026-08-30T03:00:00.000-07:00 | With offset |
...IsMissing | false | -999999 or physically impossible |
...IsSuspect | false | The measurement itself was affected |
...IsProvisional | true | Will be revised later |
...Qualifiers / ...QualifierMeanings | P / Provisional - subject to revision | Raw codes and plain English |
...Sensor | Radar | Which sensor block was used, when the gauge has several |
freshestAgeHours | 1.6 | Age of the newest measurement on this row |
parametersObserved / parametersTotal | 2 / 3 | How much this gauge actually reported |
source | USGS Water Services NWIS (official, public domain) |
A real row
{"siteCode": "09379025","siteName": "CHINLE CREEK AT CHINLE, AZ","latitude": 36.155,"longitude": -109.5375,"stateFips": "04","timeZone": "MST","streamflow": 0,"streamflowUnit": "ft3/s","streamflowObservedAt": "2026-08-30T03:00:00.000-07:00","streamflowAgeHours": 1.6,"streamflowIsMissing": false,"streamflowQualifiers": "P","streamflowQualifierMeanings": "Provisional - subject to revision","streamflowIsProvisional": true,"streamflowIsSuspect": false,"gageHeight": 2.2,"gageHeightUnit": "ft","gageHeightAgeHours": 1.6,"freshestAgeHours": 1.6,"parametersObserved": 2,"parametersTotal": 3,"source": "USGS Water Services NWIS (official, public domain)"}
Input
{"sites": ["01646500", "01463500", "07010000", "05331000", "06934500","03294500", "02358000", "08279500", "14105700", "12510500"],"states": [],"parameterCodes": ["00060", "00065", "00010"],"maxRetries": 4}
sites- USGS gauge site numbers, 8 to 15 digits including the leading zero. Find them athttps://waterdata.usgs.gov/nwis/rt. Defaults to ten major US river gauges.states- two letter state codes such asvt,tx. Returns every active gauge in those states, which can be several hundred rows per state. Takes priority oversites.parameterCodes-00060streamflow,00065gage height,00010water temperature. Anything else is ignored so the columns stay identical on every row.maxRetries- attempts when USGS returns a server error.
What it does when something is wrong
It tells you, instead of returning a clean-looking empty result.
- If none of the site numbers or state codes you gave are usable, the run fails and says so. It does not quietly fall back to the default gauges and charge you for rivers you did not ask about. (
1646500with the leading zero dropped is a realistic typo, and it is rejected rather than substituted.) - A
4xxfrom USGS is reported as a rejected request, not as an outage, and is not retried - retrying a bad site number just wastes your time. - USGS Water Services returns HTTP 503 often (2 of the first 3 calls on the morning this was built). That is retried, and if it still fails the run fails with the reason in
RUN_ISSUESrather than delivering an empty dataset. - A response whose shape is not what USGS documents throws instead of returning zero rows.
- If you set a maximum total charge and the run hits it, the run stops and says the result is incomplete.
Pricing
Pay per result: one charge per gauge site row delivered. Failed runs deliver nothing and charge nothing.
Source and licence
All data comes from the US Geological Survey Water Services (waterservices.usgs.gov), a work of the US federal government and therefore in the public domain. This Actor adds the flattening, the missing-value and range handling, the sensor selection, the freshness figures and the quality-code translation described above.