A day-by-day forecast series for one location, in one call
An agent planning energy, logistics or field work over a week needs the whole daily series, not one call per day: min/max temperature, total precipitation and peak wind for every day to the horizon.
By Matthias Begot · · Updated
An agent planning a week — scheduling energy dispatch, sequencing deliveries,
picking a spray window on a farm — does not need one forecast instant. It needs
the whole window: minimum and maximum temperature, total precipitation and
peak wind for every day from today to the planning horizon. One paid call —
GET /weather/forecast/daily — returns
that series for a GPS point or a city name, one row per UTC calendar day,
settled as one x402 payment for the entire series instead of a settlement
per lead time.
The problem: weekly planning is many targets, and polling multiplies calls
The single-instant endpoint,
GET /weather/forecast, answers one point and
one target per call — the right shape when the question is “what happens here
at hour 24?” (see
A weather forecast by GPS coordinates or city, pay per call).
But a planning agent’s question is a series: seven days, fourteen days, the
whole covered window. Polling that lead time by lead time means one HTTP
round-trip, one 402 challenge and one settlement per target — and then the
agent still has to aggregate 3-hourly steps into daily minima, maxima and
precipitation totals itself.
The daily endpoint collapses that loop. The agent states the point and the number of days; the service does the per-day aggregation from the same NOAA GRIB data and returns the finished series in a single response — a single settlement, whatever the length of the window.
The call: a point (or a city) and a number of days
Locate the point either with coordinates or with a place name — never both —
and optionally bound the series with days (an integer from 1 to 35,
defaulting to 16):
GET /weather/forecast/daily?lat=48.8566&lon=2.3522&days=7
GET /weather/forecast/daily?city=Zurich&days=7
GET /weather/forecast/daily?lat=48.8566&lon=2.3522&days=10&variables=temperature,precipitation
Place names resolve against an embedded GeoNames gazetteer — exact match,
case- and accent-insensitive, ambiguity resolved by population and narrowed
with country= — and the resolved place is echoed back in data.location, so
the agent can verify which Zurich answered before acting on the numbers.
The series always starts at the current UTC day and runs forward: there is
no from/to, because this endpoint is a forward window, not a historical
range. For the past, the twin surface is
GET /climate/point over ERA5 reanalysis.
What the agent gets back: one summary row per covered UTC day
The response is the same UnifiedResponse shape as every Invoket endpoint — a
data block plus provenance. Inside data, days[] carries one element per
covered UTC calendar day, in date order:
| Field | What the agent learns |
|---|---|
temperature_min_c / temperature_max_c | daily 2 m temperature extremes, Celsius |
precipitation_sum_mm | total precipitation over the day, millimetres |
wind_speed_max_ms | maximum 10 m wind speed of the day, m/s |
source | the model that served this day — never mixed within a day |
steps_used | how many forecast steps actually backed the summary |
coverage | per-day completeness, with a reason when partial |
Alongside the rows, grid names the cell that actually answered (with its
distance from the requested point), lead.cycle names the analysis cycle, and
a top-level coverage block states whether the whole requested range was
served in full.
Two registers: deterministic days first, ensemble-mean days after
The series is backed by two public NOAA models. The Global Forecast System (GFS) is the deterministic register, on roughly a 0.25° mesh with forecasts out to 16 days. Beyond it, the Global Ensemble Forecast System (GEFS) — a 31-member ensemble whose 00 UTC cycle extends to 35 days — supplies the extended window as an ensemble mean on a coarser 0.5° mesh. Both are public-domain U.S. government data.
The endpoint chooses the source per day and says so: a day fully covered by
the deterministic GFS is served from it; a later day is served from the GEFS
ensemble mean, and its source field names it explicitly. An ensemble mean is
a smoothed central estimate, not a deterministic run — an agent weighing a
day-25 number should treat it accordingly, and the response gives it exactly
the metadata to do that.
Coverage honesty: partial days are marked, never hidden
The daily rows are derived summaries, and the endpoint is explicit about how:
- Grid cell, not station. Values come from the nearest model grid cell —
about 0.25° in the GFS register, 0.5° in the ensemble register — not a
weather-station reading.
grid.distance_kmquantifies the gap. - Sub-sampled extremes. Min/max temperature are the extremes of the ingested 3-hourly steps, not the model’s own daily TMAX/TMIN fields; the true extreme can be missed by a few tenths of a degree.
- Partial days are flagged. Day zero starts at the analysis cycle rather
than at midnight, so it is usually
complete: falsewith a statedreason; the same applies to a day cut at the window end or missing a family value. - Uncovered days are omitted, not invented. Asking for more days than the
window covers is never an error: absent days simply do not appear in
days[], and the top-levelcoveragesays how many fell outside. The agent never has to shrinkdaysto dodge a 400.
The x402 golden rule, applied to a series
The agent pays for the answer to its question. A well-formed request that
returns at least one usable day is a 200 — including a series with a
partial first day or a grid gap, both reported through coverage. Only
requests the service cannot answer leave the 200 range: invalid coordinates or
an unresolvable place name, an out-of-bounds days, or a range with no
covered day at all (OUT_OF_RANGE). And if no forecast cycle has been ingested
yet, the service returns 503 NO_FORECAST_AVAILABLE — a transient,
no-charge state, never a paid partial answer.
Pricing is flat per call for the whole series; the authoritative figure — like every price and accepted rail — is served live by the catalog, never hardcoded here.
A network of sites: the batch companion
For a portfolio of locations,
POST /weather/forecast/batch resolves
many point-and-target forecasts in one call and one settlement, priced per
query. Its items are single instants — each carries lat/lon and exactly one
target (horizon_h, valid_time or date) — so a multi-site weekly plan is
expressed as a fan-out of site × date items within the published batch cap,
with per-item coverage verdicts and partial success (one uncovered site never
fails the batch). Note the scope differences from the daily endpoint: batch
items take explicit coordinates only (no city names), and the batch returns
instant values, not pre-aggregated daily summaries.
The practical split: one site, whole window → the daily series; many sites, specific targets → the batch.
Where it fits in the x402 loop
The call follows the same cycle as every Invoket endpoint — discover the
endpoint, receive a 402 challenge, pay, replay. The
Quickstart walks that loop with runnable snippets, and
For agents covers the discovery surfaces and the live
/catalog.
Used for what it is — a reproducible day-by-day summary of public NOAA forecast
data, with the serving model, grid cell and completeness of every single day
exposed honestly — GET /weather/forecast/daily turns “poll the forecast all
week” into one paid call. For the full field reference, place-name contract and
error codes, see the
GET /weather/forecast/daily documentation.