# 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. Published 2026-07-11 · Updated 2026-08-15 · HTML version: https://invoket.com/blog/a-day-by-day-forecast-series-in-one-settlement --- 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`](/docs/api/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`](/docs/api/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](/blog/a-forecast-for-any-location-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): ```http 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`](/docs/api/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)](https://www.ncei.noaa.gov/products/weather-climate-models/global-forecast) is the deterministic register, on roughly a 0.25° mesh with forecasts out to 16 days. Beyond it, the [Global Ensemble Forecast System (GEFS)](https://www.noaa.gov/media-release/noaa-upgrades-global-ensemble-forecast-system) — 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_km` quantifies 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: false` with a stated `reason`; 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-level `coverage` says how many fell outside. The agent never has to shrink `days` to 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](https://api.invoket.com/catalog), never hardcoded here. ## A network of sites: the batch companion For a portfolio of locations, [`POST /weather/forecast/batch`](/docs/api/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](/docs/quickstart) walks that loop with runnable snippets, and [For agents](/docs/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](/docs/api/weather-forecast-daily).