Climate Normals

Climate Normals

Agriculture Weather Credits / request: 5

Multi-year monthly averages for a point: temperature, total precipitation, rainy/frost days, GDD and ET0. Weather data © Open-Meteo / OpenWeather / MET Norway.

GET https://api.apikodu.com/api/v1/climate/normals
Documentation
Overview

Multi-year monthly normals for a point: temperature means, monthly precipitation totals, rainy/frost day counts, GDD (base 10 °C) and ET0. Values are interpolated from the 4 surrounding cells. Weather data © Copernicus ERA5 / ERA5-Land (contains modified Copernicus Climate Change Service information) / Open-Meteo / OpenWeather / MET Norway.

Authentication

Every request requires the x-api-key header. Credits used and remaining quota are returned in response headers (x-api-credits-used, x-api-remaining-credits, x-rate-limit-*).

Request
GET https://api.apikodu.com/api/v1/climate/normals?latitude=39.92&longitude=32.87
GET query.
Parameters
Name Type Required Default Options Description
latitude number * Required — — Point latitude -90..90.
longitude number * Required — — Point longitude -180..180.
month integer Optional — — 1–12. All 12 months when empty.
years integer Optional 2 — How many years back to average. Default 2; larger values are capped by the stored history of 730 days.
Response
Name Type Description
sampleFrom string Sample window start YYYY-MM-DD.
sampleTo string Sample window end YYYY-MM-DD.
gddBaseC integer GDD base temperature °C (10).
months array Normals for the requested months.
months[].month integer Month 1–12.
months[].tminMeanC number Mean daily minimum temperature °C.
months[].tmaxMeanC number Mean daily maximum temperature °C.
months[].tmeanMeanC number Mean daily mean temperature °C.
months[].precipTotalMeanMm number Multi-year mean of monthly total precipitation mm.
months[].rainyDaysMean number Mean number of rainy days (≥1 mm).
months[].frostDaysMean number Mean number of frost days (tmin ≤ 0 °C).
months[].gddMean number Multi-year mean of monthly GDD sum (base 10, cap 30).
months[].et0TotalMeanMm number Multi-year mean of monthly ET0 sum mm.
months[].sampleYears integer Number of years with data for that month.
gridLatitude number Latitude of the 0.1° grid corner around the request (interpolation reference).
gridLongitude number Longitude of the 0.1° grid corner.
gridInterpolated boolean true: values bilinearly blended from the 4 surrounding cells. false: single cell.
sources array Data sources that contributed: copernicus-era5-land, open-meteo, openweather, met-norway. For past days (older than about a week) Copernicus ERA5 / ERA5-Land takes precedence; UV, precipitation probability and the weather code of wet hours / days are derived from ERA5-Land variables, wind gust comes from ERA5 (0.25°); cloud cover and the weather code of dry hours / days are filled from other sources when available. At coastal / sea points ERA5-Land values come from the nearest land grid point.
disclaimer string Decision-support disclaimer and source attribution.
Errors
HTTP code Description
400 -257 latitude/longitude missing or out of range (lat -90..90, lon -180..180).
400 -258 fromDate/toDate not YYYY-MM-DD, range exceeds 366 days, or outside the last 2 years / after yesterday.
400 -259 granularity/days/hours/metric/op/comparator is invalid.
429 -316 Daily new location (cell) limit (50) reached. Previously requested locations keep working; new locations next day (UTC). Retry-After header gives seconds until end of day.
503 -261 No stored weather for this location yet. Cells were created; the collector is filling them. Retry shortly.
401 -100 x-api-key is missing, empty, malformed, inactive, banned, expired, IP-restricted, or not allowed for this API.
429 -221 Per-minute request limit exceeded. Response headers: x-rate-limit-limit, x-rate-limit-remaining, x-rate-limit-reset.
429 — Package credit quota cannot cover this request. Body may be { error, limit, currentUsage, requestCost } (no code field).
500 -1 Unexpected server error. message is a generic error text without technical details.
Notes
  • Success body is { data: { ... } }. Error body is { code, message }. code is an ApiResponseCode enum value (negative integer).

Sample response

{
  "data": {
    "gridLatitude": 39.90,
    "gridLongitude": 32.90,
    "gridInterpolated": true,
    "sampleFrom": "2024-08-31",
    "sampleTo": "2026-08-29",
    "gddBaseC": 10,
    "months": [
      {
        "month": 6,
        "tminMeanC": 14.6,
        "tmaxMeanC": 28.7,
        "tmeanMeanC": 21.7,
        "precipTotalMeanMm": 33.5,
        "rainyDaysMean": 4.5,
        "frostDaysMean": 0.0,
        "gddMean": 351.2,
        "et0TotalMeanMm": 168.4,
        "sampleYears": 2
      },
      {
        "month": 7,
        "tminMeanC": 17.1,
        "tmaxMeanC": 32.4,
        "tmeanMeanC": 24.8,
        "precipTotalMeanMm": 9.0,
        "rainyDaysMean": 1.0,
        "frostDaysMean": 0.0,
        "gddMean": 458.6,
        "et0TotalMeanMm": 195.2,
        "sampleYears": 2
      }
    ],
    "sources": [
      "open-meteo"
    ],
    "disclaimer": "Multi-year monthly averages from Copernicus ERA5 / ERA5-Land, Open-Meteo, OpenWeather and MET Norway. Contains modified Copernicus Climate Change Service information. Decision support only."
  }
}

Code samples

  
      const response = await fetch('https://api.apikodu.com/api/v1/climate/normals', {
        method: 'GET',
        headers: {
          'x-api-key': 'YOUR_API_KEY'
        }
      });

      const data = await response.json();
      console.log(data);
  
  
      import requests

      headers = {
          'x-api-key': 'YOUR_API_KEY'
      }

      response = requests.get('https://api.apikodu.com/api/v1/climate/normals', headers=headers)
      print(response.json())
  
  
      using var client = new HttpClient();
      client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

      var response = await client.GetStringAsync("https://api.apikodu.com/api/v1/climate/normals");
      Console.WriteLine(response);
  
  
      $response = file_get_contents('https://api.apikodu.com/api/v1/climate/normals', false, stream_context_create([
          'http' => [
              'header' => "x-api-key: YOUR_API_KEY"
          ]
      ]));

      print_r(json_decode($response, true));
  
  
      curl -X GET 'https://api.apikodu.com/api/v1/climate/normals' \
        -H 'x-api-key: YOUR_API_KEY'
  

Start building in minutes

Create a free account, get your API key and send your first request in minutes.

Get started free