What Weather API Responses Don’t Tell You About Data Provenance (And How to Reconstruct It)

When you call a weather API and get back a temperature reading, most developers don’t ask where that number actually came from. Was it a live METAR observation from a station three kilometers away? A GFS grid cell interpolated from a model run that finished six hours ago? A blend of both? The response JSON doesn’t tell you. It just gives you a number.

That gap matters more than it sounds, especially when you’re building something that reacts to weather data rather than just displaying it.

The Provenance Problem

A “current conditions” endpoint might be returning any of three meaningfully different things:

  • A direct METAR observation from a specific ICAO-coded station, decoded and mapped to API fields
  • Output from a mesoscale NWP model — HRRR in the US runs at 3km grid spacing and updates hourly, so freshness is decent, but it’s still a model, not a measurement
  • A weighted blend, where observation data gets merged with short-term model output to fill spatial gaps or smooth out station outliers

All three are legitimate. None of them behave the same way under edge conditions.

If you’re alerting a logistics fleet that road temps are dropping toward freezing, you want a measured value from a nearby station, not a model estimate that hasn’t had a METAR correction cycle since before the cold front arrived. If you’re doing a historical backfill across a grid of agricultural land in Kansas, a model-derived value is probably fine — station coverage is sparse and HRRR output is good enough for energy-balance calculations. But you need to know which one you have to calibrate your trust accordingly.

What You Can Actually Infer from the Response

Most weather APIs, including ours, don’t expose a provenance field the way a proper data lineage system would. There are signals you can use to make educated guesses, though.

Observation Time Staleness

The last_updated timestamp in a current-conditions response is one of the more useful signals. METAR-sourced data typically arrives with observation intervals of 20–60 minutes depending on station type and whether it’s SPECI-augmented. If the observation time is more than 90 minutes old, there’s a reasonable chance you’re looking at a model-filled value — either the station dropped out or the API fell back to NWP output to fill the gap.

We’ve had to build logic around exactly this. When a METAR station hasn’t reported recently, you have to decide whether to serve a stale observation, flag it as degraded, or substitute model output transparently. Each choice has trade-offs. Serving stale data is arguably worse for fast-changing conditions — thunderstorm onset, frontal passage — than serving a model value, but model output carries its own uncertainty in convective situations where HRRR can still mistime cell development by tens of minutes.

Suspiciously Round Numbers

Not a reliable heuristic, but worth noting: model output interpolated to a point coordinate and then unit-converted tends to produce values like 14.2°C. Paradoxically, clean round numbers in a current-conditions field sometimes indicate METAR data decoded directly, since METAR temperature encoding is in whole degrees Celsius. If you’re consistently seeing temp_c: 14.0, it’s more likely from a METAR decode than from GFS output.

The Coordinate Distance Test

If you know the lat/lon of the METAR station being used — which most APIs don’t expose, and ours currently doesn’t surface in the standard response — you can compare its elevation and position against your requested coordinate. A mismatch of more than 200 meters of elevation or more than 15km horizontally is a reasonable signal that the reading may not be representative of your target location regardless of how fresh it is.

We apply lapse-rate correction for elevation differences internally before the value reaches the API response. That correction assumes a standard atmospheric lapse rate of roughly 6.5°C per 1,000 meters, which is an approximation. On a clear calm night with a strong inversion in a valley, the actual lapse rate can reverse — the valley station may be colder than the hillside — and the standard correction moves the estimate in the wrong direction. We’d rather say that plainly than imply the adjustment is more precise than it is.

A Practical Pattern: Build Your Own Confidence Score

Since the API doesn’t give you provenance directly, the move is to compute a lightweight proxy confidence score on your side before acting on the data. Something like this:

  • Parse last_updated and check age — anything over 75 minutes gets a penalty
  • If the response surfaces station coordinates, calculate distance and elevation delta from your target point and scale confidence down for large mismatches
  • Flag any reading where temp_c changes by more than 5°C between consecutive polls 30 minutes apart — that’s either a station swap or a data quality issue worth investigating rather than acting on blindly

This isn’t a substitute for genuine data lineage metadata, but it lets you make a reasoned decision about whether to surface a value to a user, hold it for review, or fall back to forecast data instead of the current-conditions reading.

When Forecast Data Is Actually More Reliable Than Current Conditions

For locations with poor station coverage — rural areas, mountain passes, offshore positions — the “current conditions” response may be sourced from a station that’s functionally unrepresentative of the target location, while the forecast data for the same coordinate is drawn from a higher-resolution NWP model grid run for that general area. HRRR’s 3km grid is specifically designed to resolve terrain effects that a single METAR station 40km away cannot capture.

In cases like that, pulling the hour[0] forecast value — the model’s analysis or earliest forecast step for the current hour — can be a more physically meaningful number for your location than whatever the nearest METAR says. It’s still model output, not a measurement. But it’s model output for the right place rather than a measurement from the wrong one.

We lean on this internally for locations where the nearest station is far enough away that raw station data would just be misleading. It’s not something we advertise, but it’s a real consequence of how station-selection and model-blending logic interact.

The Honest Limit Here

None of the inference techniques above tell you definitively what data source you got. They narrow the hypothesis space. For most applications — a web app showing current conditions, a consumer travel tool, an alerting system with human review in the loop — that’s probably enough. You’re not writing flight operations software where data provenance has to be formally traceable.

If provenance genuinely has to be auditable — certain agricultural finance products, climate risk assessments, insurance triggers — you probably shouldn’t be relying on a blended API endpoint at all. You should be ingesting raw METAR feeds from NOAA’s ADDS or equivalent and tracking source station IDs yourself. A convenience API trades traceability for ease of integration, which is a reasonable trade for most use cases, but not all of them.

The next time a reading looks off, check the observation timestamp before assuming the API is wrong. If it’s stale, check the distance to the nearest major airport or ASOS station for that region. That’s the whole story more often than you’d expect — and knowing that changes how you’d instrument your fallback logic.

Scroll to Top