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 is a successful answer -> 200, even when individual items have partial grid coverage and return null values with coverage.complete: false. Requests the service cannot answer - malformed body, empty batch, batch over the published cap, malformed item or a date outside the covered ERA5 window - 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" },
    { "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
latnumberyesLatitude in decimal degrees, from -90 to 90
lonnumberyesLongitude in decimal degrees, from -180 to 180
datestringyesUTC date to query, format YYYY-MM-DD

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 grid cell and a spatially uncovered grid cell 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": 2,
    "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"
        }
      }
    ]
  },
  "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 and moves with the ingested store. If any item asks for a date outside the covered ERA5 window, the service cannot answer the batch: the whole call returns 400 OUT_OF_RANGE, and the agent does not pay for a partial answer.

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 invalid coordinates or has an invalid YYYY-MM-DD date
400OUT_OF_RANGEAt least one item asks for a date outside the covered ERA5 window
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": "requested date is outside the covered window 2021-01-01..2026-06-20", "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.