England River Levels — Latest Gauge Readings avatar

England River Levels — Latest Gauge Readings

Pricing

$2.00 / 1,000 result rows

Go to Apify Store
England River Levels — Latest Gauge Readings

England River Levels — Latest Gauge Readings

Export public Environment Agency water-level measurements with station location, original unit, reading time and freshness flags.

Pricing

$2.00 / 1,000 result rows

Rating

0.0

(0)

Developer

Biosick Johnny

Biosick Johnny

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Security

Limited permissions

Share

Export the latest available water-level readings from the Environment Agency's public monitoring network in England. Get one clean row per measure, including its station, river, location, original unit, reading time and freshness flags. No source API key or login is required.

Use the feed for environmental dashboards, hydrology research, station inventories with current measurements, and scheduled data exports into a spreadsheet or database. Apify can export the dataset as JSON, CSV, Excel and other supported formats after deployment.

Quick start

{
"riverName": "River Thames",
"maxItems": 100,
"staleAfterHours": 24,
"proxyConfiguration": { "useApifyProxy": false }
}

River, town and catchment names use the source's exact, case-sensitive spelling. Use River Thames, not Thames. All supplied filters are combined. For one known gauge, use stationReference, for example 3400TH. Leave filters blank to search the available England network. Start with a small maximum.

What you receive

Each row identifies a measure, not a whole station. One gauge may expose upstream/downstream readings or several units and therefore return multiple rows. For example, mASD is relative to a station datum while mAOD is relative to Ordnance Datum; they must not be treated as interchangeable river depths or compared across gauges as a flood ranking.

The complete real sample is in ./SAMPLE_OUTPUT.json. The most useful fields are:

FieldsMeaning
measureId, stationReference, stationNameStable source measure identity and station information
riverName, town, catchmentNameSource location labels, when published
latitude, longitude, stationStatusPublished coordinates and station status
value, unit, qualifier, periodSecondsOriginal measurement, its unit, context and nominal measurement period
readingDateTime, readingAgeHoursReading timestamp and age at readings retrieval
isStale, readingInFuture, hasReadingExplicit data-quality/freshness flags
stationUrl, readingUrl, retrievedAtPrimary-source links and UTC retrieval timestamp
source, licence, attributionSource credit and reuse information

Missing optional metadata is null. Zero and negative values are preserved. A reading without a finite scalar value or a timezone-qualified timestamp is treated as missing. Stale values are flagged and retained. If includeMissingReadings is false, measures without a valid reading are omitted; if true, they have value, readingDateTime, readingAgeHours and freshness flags set to null, and hasReading: false.

Input

InputDefaultDetails
riverNameemptyExact river name
townemptyExact source town name
catchmentNameemptyExact catchment name
stationReferenceemptyExact Environment Agency reference; also narrows the readings feed
searchemptySource text search in station labels
maxItems100Hard maximum delivered measure rows, 1–10,000
pageSize100Station page size, 1–500; smaller pages require more requests
staleAfterHours24Age above which isStale is true; integer 1–8,760
includeMissingReadingsfalseInclude null-reading rows; these also count and are billable if enabled
requestIntervalMillis1,000Minimum time between request starts, 1,000–60,000 ms
maxRequests100Maximum source HTTP attempts including retries and empty end pages, 2–1,000
proxyConfigurationdirectOptional Apify/custom proxy configuration; no source proxy is required

Text filters are at most 200 characters. Unknown input fields are rejected. Optional proxies need the user's own later configuration and can carry provider costs. They are not rotated to bypass access restrictions.

Output example

A shortened real row collected on 26 October 2026 (historical sample, not a current observation):

{
"measureId": "https://environment.data.gov.uk/flood-monitoring/id/measures/3400TH-level-stage-i-15_min-mASD",
"stationReference": "3400TH",
"stationName": "Kingston",
"riverName": "River Thames",
"unit": "mASD",
"qualifier": "Stage",
"value": 4.548,
"readingDateTime": "2026-10-26T16:30:00.000Z",
"readingAgeHours": 0.337,
"hasReading": true,
"isStale": false
}

The complete verified record, with source links and attribution, is in ./SAMPLE_OUTPUT.json. Retrieve the source again for current observations.

Pricing

Price: $2.00 per 1,000 delivered measure rows ($0.002 per dataset item), no start fee, billed via Apify pay-per-event (apify-default-dataset-item only). Source data is free; Apify platform usage for a run is included in the price shown on the Actor page. The charge pays for the maintained Actor, normalization and Apify integration.

maxItems bounds row count. A missing-reading row costs the same if you explicitly enable it. Repeated measures within one run are deduplicated. Scheduled runs are independent snapshots: receiving the same measure again in a new run is a new result. An empty result creates no result event. Network failures before delivery create no result event; a storage failure can leave already delivered and charged rows.

Reliability and source etiquette

The Actor uses the official JSON API with one request at a time. It reads the bulk latest-readings feed and joins it to station pages, avoiding one latest-reading request per station. An exact station reference narrows the readings request. The source recommends collecting latest readings no more often than every 15 minutes; use that minimum schedule interval.

Transient network errors, HTTP 408, 429 and 5xx responses get up to three retries with backoff. Retry-After is honored; a requested wait over two minutes stops the run so it can be retried later. Other rejected HTTP requests and malformed response envelopes fail immediately. The request budget is enforced across both phases and all retries.

Station pages can contain fewer distinct stations than the requested limit. Pagination continues until an empty page, an output cap, or a failure, and deduplicates by measure identity. Exhausted retries, unexpected pagination, repeated pages and request-budget exhaustion fail the run before any dataset rows are written. Results are prepared in memory before delivery; an aborted preparation does not deliver a partial scan.

RUN_SUMMARY in the default key-value store records stopReason (sourceExhausted, maxItems, or budgetReached), request/retry counts, scan counts and missing/invalid readings. If maxItems was reached, the result is intentionally capped; it is not a complete network export. All rows share the readings retrieval time. The separate source calls are not a transactional snapshot, so a station or reading can change during a run.

FAQ

Does it cover all of the UK? The source is the Environment Agency network in England and may include cross-border gauges. Scotland, Wales and Northern Ireland have separate services; no complete UK coverage is promised.

Are these flood warnings, forecasts or historical records? This Actor returns the latest published measurements only. It does not determine flood severity, provide forecasts or reconstruct a complete historical time series. Store snapshots yourself if useful, but readings can arrive in batches between runs.

Why is a reading old? Measurement and transmission schedules differ by station. A nominal 15-minute sampling period does not guarantee a new published observation every 15 minutes. Consult readingDateTime and the freshness fields.

Why are there fewer rows than requested? There may be fewer matching measures, missing readings are excluded by default, or the user spending cap was reached. Check RUN_SUMMARY. An unknown exact river name can legitimately return zero rows.

Can I resume a failed run in the same dataset? Preparation can be rerun while the dataset is empty. If a process is restarted after it began delivery, a non-empty dataset is rejected to prevent duplicate rows and billing. Start a fresh run and inspect any already delivered rows. Automatic continuation of partially delivered datasets is not supported.

Can I use the source directly? Yes. The official API is public, free and keyless. This Actor supplies convenient maintained output and platform integration.

Run locally

Requires Node.js 22 or later. From this Actor directory:

npm ci
npm test
npm run smoke

In this workspace npm was bootstrapped locally because it was absent from PATH. The equivalent commands are:

node ../.tools/npm/bin/npm-cli.js ci --cache ../.npm-cache
node ../.tools/npm/bin/npm-cli.js test --cache ../.npm-cache
node scripts/smoke.js live

The smoke script runs node src/main.js in a fresh local storage directory, supplies the sample input, excludes account credentials from its environment, verifies five rows against their exact official reading URLs, and refreshes the sample. It enables process-only local memory metrics because this machine's restricted environment prevents Crawlee from spawning ps; cloud runs keep standard Apify container metrics.

Additional checks:

node scripts/smoke.js empty
node scripts/smoke.js budget
node scripts/smoke.js zero-budget

Budget mode uses the SDK's local PPE simulation ($1 per synthetic event) with a $2 limit; it spends no money. Do not enable local PPE test variables on Apify.

For a manual run, put your JSON input in storage/key_value_stores/default/INPUT.json, then run:

env -u APIFY_IS_AT_HOME APIFY_PURGE_ON_START=false APIFY_LOCAL_STORAGE_DIR=./storage CRAWLEE_STORAGE_DIR=./storage CRAWLEE_LOCAL_PROCESS_METRICS=true node src/main.js

Use a fresh storage directory for each independent run. Leave APIFY_IS_AT_HOME unset locally: the pinned SDK treats any nonempty value, including false, as cloud mode. The Dockerfile uses the official Apify Node.js 22 image, a lockfile and production-only dependencies.

Environment Agency flood-monitoring API (Beta). The source expressly provides programmatic access without registration under the Open Government Licence v3.0.

This uses Environment Agency flood and river level data from the real-time data API (Beta). Keep this credit and the licence when redistributing output. This is an independent tool with no Environment Agency endorsement. It collects public station and sensor data, without personal contact information or private content.

The source is provisional, can be delayed or unavailable, and provides no service guarantee. It must not be relied on for safety-critical decisions; use the official flood-warning channels for those purposes. Review the current source terms and licence before redistribution.