POST /climate/point/batch

Resolves many GPS point and date pairs in a single call against the ERA5 reanalysis store. Each item uses the same local GRIB-decoded lookup engine as GET /climate/point: 2 m temperature, total precipitation and 10 m wind for a dated location, with grid and coverage metadata that let an agent judge the answer.

Use this endpoint when the agent has a portfolio of sites, parcels or assets to score at once: parametric insurance checks, agricultural field reviews, energy asset screening or logistics analysis. The batch is settled as one x402 payment for the whole call and priced per query by the gateway. See the live /catalog for the authoritative endpoint listing, pricing model and batch cap.

x402 golden rule: the agent pays for the answer to its question. A well-formed batch with at least one covered item is a successful answer -> 200, even when other items have a grid gap or ask for a date outside the covered ERA5 window: those items remain verdicts in results, with null values and coverage.complete: false (partial success). Requests the service cannot answer - malformed body, empty batch, batch over the published cap, a malformed item, or a batch where no item at all is covered - leave the 200 range.

Request

POST with a JSON body. Set Content-Type: application/json.

POST /climate/point/batch
Content-Type: application/json
{
  "queries": [
    { "lat": 48.8566, "lon": 2.3522, "date": "2024-07-14" },
    { "city": "Zurich", "date": "2024-07-14" },
    { "lat": 40.7128, "lon": -74.006, "date": "2024-01-20" }
  ]
}
FieldTypeRequiredDescription
queriesobject[]yesPoint queries to resolve, from 1 item up to the batch cap advertised in the live catalog
latnumbercoordinate modeLatitude in decimal degrees, from -90 to 90
lonnumbercoordinate modeLongitude in decimal degrees, from -180 to 180
citystringplace-name modePlace name instead of coordinates, for example "city": "Zurich"
locationstringnoStrict alias of city; if both are present they must be identical
countrystringnoISO-3166 alpha-2 code narrowing an ambiguous place name
datestringyesUTC date to query, format YYYY-MM-DD

Each item locates its point either with lat/lon coordinates or with a place name via city (alias location) - the same gazetteer contract as the single endpoint, and the resolved place is echoed back in that item’s location field. An item with neither a point nor a place name, out-of-bounds coordinates or a malformed date rejects the whole batch with a 400 naming the item’s index - nothing is charged. An item whose place name is unknown or ambiguous (an unresolvable city, a city/location mismatch, or a place name given together with coordinates) does not fail the batch: it stays in results as a degraded verdict - coverage.complete: false with a guiding reason, only the echoed date, no coordinates and no values - and is not part of what the agent pays for.

Batch items always request the full climate point payload. For field-level details, including temperature, precipitation, wind, grid and coverage, see the single-call reference.

200 response - UnifiedResponse

{
  "data": {
    "count": 2,
    "results": [ { ... }, { ... } ]
  },
  "provenance": {
    "source": "era5-copernicus",
    "fetched_at": "2026-06-20T12:00:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-19T00:00:00Z" }
  }
}
  • count: number of point queries resolved, equal to results.length and to the number of submitted items.
  • results: one verdict per query, in the same order as the input. Each element has the same shape as the data object returned by GET /climate/point.
  • A single provenance block covers the whole batch. ERA5 values are derived from Copernicus Climate Change Service information and served from the same snapshot for every item in the call.

Example - mixed coverage batch

A covered item and an uncovered one - a grid gap, a date outside the covered window, or an unresolvable place name - can coexist in the same paid answer. The uncovered item remains a verdict in results; it does not make the whole batch fail.

{
  "data": {
    "count": 3,
    "results": [
      {
        "lat": 48.8566,
        "lon": 2.3522,
        "date": "2024-07-14",
        "temperature": { "celsius": 24.3 },
        "precipitation": { "total_mm": 0.4 },
        "wind": { "speed_ms": 3.09, "direction_deg": 139.7 },
        "grid": { "lat": 49.0, "lon": 2.0, "distance_km": 30.27 },
        "coverage": { "complete": true }
      },
      {
        "lat": 10.0,
        "lon": 80.0,
        "date": "2024-07-14",
        "temperature": { "celsius": null },
        "precipitation": { "total_mm": null },
        "wind": { "speed_ms": null, "direction_deg": null },
        "grid": { "lat": 10.0, "lon": 80.0, "distance_km": 0.0 },
        "coverage": {
          "complete": false,
          "reason": "no data at this grid cell for: temperature, precipitation, wind"
        }
      },
      {
        "date": "2024-07-14",
        "coverage": {
          "complete": false,
          "reason": "unknown place 'Xyzzy'; narrow with 'country' (ISO-3166 alpha-2) or provide lat/lon"
        }
      }
    ]
  },
  "provenance": {
    "source": "era5-copernicus",
    "fetched_at": "2026-06-20T12:00:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-19T00:00:00Z" }
  }
}

Coverage honesty

ERA5 is a gridded reanalysis, not a weather station reading. Each result is the nearest or interpolated grid value served for that item, with the same coverage semantics as the single endpoint. A spatially uncovered grid cell can return 200 with null values and coverage.complete: false.

The historical window is finite, moves with the ingested store, and differs by variable exactly as on the single endpoint: 2 m temperature and total precipitation cover a rolling 30-year window (the WMO-standard climatological period), 10 m wind a rolling ~5-year window. An item that asks for a date outside the covered window is a per-item failure, not a batch failure: it stays in results as a verdict with null values and coverage: { "complete": false, "reason": "date outside the covered window" }, while the covered items around it are served normally. Only a batch where no item is covered in date returns 400 OUT_OF_RANGE - zero values delivered, so the agent pays nothing.

Batch cap and settlement

The gateway prices this endpoint per query and settles the batch as one x402 payment for the call. The current cap and pricing model are published in the live /catalog, including the unit field used for the batch size. The request body uses that same field, queries.

An oversized batch is rejected before any lookup work is performed, so it is not a paid answer. Split larger portfolios into multiple calls using the catalog’s published cap.

Errors

Only requests the service cannot answer leave the 200 range.

StatuscodeCase
400INVALID_BODYBody missing, not JSON, not an object, or queries missing
400EMPTY_BATCHqueries is an empty array ([])
400BATCH_TOO_LARGEMore point queries than the published batch cap
400INVALID_QUERYAn item is malformed, has out-of-bounds coordinates, provides neither coordinates nor a place name, or has an invalid YYYY-MM-DD date
400UNKNOWN_LOCATIONNo item in the batch resolved to a point (every place name unknown, or place-name resolution unavailable on the deployment)
400OUT_OF_RANGENo item in the batch is covered by the store window (a batch with at least one covered item is a 200 with per-item verdicts)
500INTERNALInternal error (detail logged, not exposed)
{ "error": "missing 'queries' array in request body", "code": "INVALID_BODY" }
{ "error": "'queries' must contain at least one item", "code": "EMPTY_BATCH" }
{ "error": "batch exceeds the published maximum number of queries", "code": "BATCH_TOO_LARGE" }
{ "error": "query at index 0: invalid date '14-07-2024', expected YYYY-MM-DD", "code": "INVALID_QUERY" }
{ "error": "no query resolved to a point: check the place names, narrow with 'country' (ISO-3166 alpha-2), or provide lat/lon", "code": "UNKNOWN_LOCATION" }
{ "error": "requested date is outside the covered window 1996-06-15..2026-06-14", "code": "OUT_OF_RANGE" }

See also

  • GET /climate/point - single point/date reference and full field documentation.
  • For agents - discovery surfaces, the live /catalog and how settlement works.