Climate API
Eighty-seven years of daily climate, everywhere on land, from one archive — 1 January 1940 to within a week of today, on the ERA5 grid at 0.25° (about 28 km). Answers is this normal?, with the evidence.
Daily climate#
climate2 credits, +1 per complete 365.25-day period in the spanThirteen daily fields for any land coordinate, 1940 to last week.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
lat | float | — | Required. Any coordinate on land; the archive is global. |
lon | float | — | Required. |
start | ISO date | 1 Jan of the end year | Span is capped per request — see Plans. |
end | ISO date | the archive's last day | |
fields | csv | temperature and precipitation | Ask /v1/climate/fields what this run can answer for. |
series | bool | true | Include the day-by-day values. Set false when you only want the aggregates. |
format | string | json | json or csv. CSV is a paid-plan feature and returns the monthly rows. |
This is not the hourly history with
a GROUP BY in front of it. The daily fields are derived once, at
ingestion, on a day boundary chosen for the physics rather than for convenience,
and the derived fields — apparent temperature, sunshine duration, mean humidity —
are computed from the full hourly series rather than from the daily extremes.
Days are cut at solar midnight, not at the political time
zone. The offset is round(longitude / 15).
This is a deliberate choice and it is measurable: aggregating on UTC instead biases the daily minimum by 2.1 °C at Alice Springs, because the minimum falls just before dawn. A political time zone is worse still — two neighbouring cells either side of a border would have their days cut at different moments, and a map of daily maxima would show the outline of the time zones.
Values are the grid cell's, not the point's. We do not adjust temperature to your exact elevation. Providers that do will therefore differ from us by a few tenths of a degree at the same coordinate — up to 0.4 °C in our own measurements — and neither figure is wrong. Ours is what the reanalysis says for that cell; theirs is that value plus a lapse rate applied to an elevation difference. We publish the cell so you can tell which you are getting: see coverage and cells.
Monthly aggregates#
climate2 credits, +1 per complete 365.25-day period in the spanThe same fields aggregated by calendar month.
Sums for the accumulations, means and extremes for the rest. Same price as the daily series, because it reads the same column.
Ask for it when a monthly figure is what you actually plot, rather than fetching thirty times the data and reducing it yourself — the transfer is the slow part, not the arithmetic.
The climate of a place, in one call#
climate3 credits, +1 per complete 365.25-day period in the spanMonthly normals, annual series, records, trends and Köppen — no span limit.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
lat | float | — | Required. |
lon | float | — | Required. |
start | ISO date | the archive's first day | Asking for the whole record is the normal way to use this. |
end | ISO date | the archive's last day | |
daily | bool | false | Add day_normals: the normal of each calendar day of the year over your window, with the number of observations behind each one. |
Everything a climate page states about a location, already reduced: twelve monthly normals, one row per complete calendar year, the all-time records with the dates they fell on, the least-squares warming trend with its significance, and the Köppen-Geiger code. For any land coordinate on Earth.
It is priced by span, and the default span is the whole archive.
Priced at 3 credits, +1 per complete 365.25-day period in the span — so a call with no
start covers 1940 to today and costs
89 credits, not one. On the free plan that
is roughly 110 calls a month.
That is still the cheap way to get this answer: assembling it yourself would take nine capped /v1/climate/daily calls over the same span, which cost more between them and return thirty-one thousand rows you then have to reduce. But it is not a lookup, and a page that calls it per visitor will empty a quota. Cache it — the answer for a coordinate changes once a day at most.
Pass start when you do not need the whole record: thirty years
costs 32 rather than 89.
No span limit here, unlike /v1/climate/daily.
That limit exists because a caller who can pull the day-by-day series can rebuild
the archive; this endpoint returns no series at all. The full record comes back as
about 62 kB — 100 kB with daily=true — against the thirty-one
thousand daily rows it was reduced from, so it reconstructs nothing. One request
replaces the nine capped daily calls the same answer would otherwise take.
daily=true is not the same as normals?daily=true
And the difference is the point. The normals endpoint averages over a thirty-year WMO window; this one averages over whatever window you asked for — the whole archive by default.
It is the only way to say "9.4 °C above normal for a 30 July" with
eighty-seven years behind the claim rather than thirty. Each day carries its
sample count, so widening to a fifteen-day centred normal is
Σ(mean·samples) / Σ(samples) — exact, and without a second
request.
Two conventions to know before you compare with another source
A calendar year enters the annual series and the trend only if the archive holds at least 360 of its days, so the year in progress is excluded. A half-year reads as a collapse in rainfall and drags a trend line with it.
trends is null below ten complete years. Under that,
a slope is weather noise wearing a climate signal's clothes, and we would rather
publish nothing than a confident wrong number. Each trend carries its own
p_value and significant flag for the same reason — read
them before you quote the slope.
WMO normals#
normals3 creditsA thirty-year mean over a WMO reference period.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
lat | float | — | Required. |
lon | float | — | Required. |
period | string | 1991-2020 | 1991-2020 or 1961-1990. Both are WMO reference periods. |
fields | csv | temperature and precipitation | |
daily | bool | false | Include the 366 per-day normals with their spreads, and the record high and low for each calendar day. |
A normal is not an average of whatever period you happened to ask for. It is a thirty-year mean over a window the World Meteorological Organization fixes, so that two people quoting a normal are quoting the same thing.
This needs the normals scope, which
the daily archive does not. A key that reads
/v1/climate/daily happily can still get 403 scope_denied
here — see Plans for which tier includes it.
If what you want is "the normal over the whole record" rather than over a WMO
window, use /v1/climate/summary instead — it needs
only the climate scope and gives you eighty-seven years instead of
thirty.
Comparing two normals#
normals6 creditsBoth WMO periods and the change between them, in one call.
This is the question most people are really asking when they ask for a normal — not "what is normal here" but "how much has normal moved".
Answering it in one request means the two halves cannot come from different runs, which is the failure mode of computing it yourself from two calls: the archive advances between them, and the difference you publish then contains a version change as well as a climate change.
Coverage, fields and cells#
The run being served and the dates it spans. No key needed.
What this run can answer for, with units, and which fields are derived. No key needed.
climate1 creditWhich cell answers for a point, and how far it is.
The licence terms for this archive. No key needed.
cells/resolve answers the question every gridded product should be
asked before it is trusted: which cell am I actually reading, and how far is
it from the point I asked about? At 28 km that distance can be 20 km, and
knowing it is the difference between quoting a number and quoting a number
responsibly.
fields is the same contract as
/v1/historical/variables: it lists what the run
holds rather than what the product might one day hold, so a client built against
it does not break when the archive grows.
Pin the cell rather than the coordinate when a baseline has to stay comparable over years. A coordinate is stable, but the cell that serves it would move if the grid ever changed — and a baseline that moves silently is the failure mode this endpoint exists to prevent. The degree-days API has the same pattern, with a dedicated path: see pinning a cell.