Weather History

Weather History

Agriculture Weather Credits / request: 3

Daily or hourly historical weather for a point (up to the last 2 years). Temperature, precipitation, wind, humidity, ET0 and more. Weather data © Open-Meteo / OpenWeather / MET Norway.

GET https://api.apikodu.com/api/v1/weather/history
Documentation
Overview

Daily or hourly historical weather for a point (up to 2 years). Values are bilinearly interpolated from the 4 surrounding cells. On days sourced from ERA5-Land, precipitation probability (from observed precipitation; 0–1, share of surrounding cells with precipitation), UV index (approximate, from solar radiation) and the weather code of wet hours / days (from precipitation and snow; no fog, shower or thunderstorm distinction) are derived values; UV is daily only. Cloud cover and the weather code of dry hours / days are not derived from ERA5; they come from other sources when available, otherwise null. Wind gust comes from ERA5 (0.25° grid). 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/weather/history?latitude=39.92&longitude=32.87&fromDate=2026-06-01&toDate=2026-06-30
GET query.
Parameters
Name Type Required Default Options Description
latitude number * Required — — Point latitude -90..90.
longitude number * Required — — Point longitude -180..180.
fromDate string * Required 2026-06-01 — Start YYYY-MM-DD. At most 2 years ago. Range ≤ 366 days.
toDate string * Required 2026-06-30 — End YYYY-MM-DD. At most yesterday.
granularity string Optional daily daily hourly daily or hourly. Default daily.
fields string Optional — temp tmin tmax tmean precip precipprob snow wind windgust winddir humidity pressure cloud uvi dewpoint et0 sunrise sunset daylight weathercode Comma-separated field list. All fields when empty. Valid keys are listed under Options (tmin/tmax/tmean/precip... daily only, temp hourly only).
Response
Name Type Description
granularity string Granularity used.
fromDate string Window start YYYY-MM-DD.
toDate string Window end YYYY-MM-DD.
daysTotal integer Calendar days in the window.
daysWithData integer Days with data (daily).
hoursWithData integer Hours with data (hourly).
missingCount integer Days without data.
missingDates array YYYY-MM-DD list of missing days (first 10).
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.
daily array Daily rows when granularity is daily.
daily[].date string Day YYYY-MM-DD (UTC).
daily[].tmin number Minimum temperature °C.
daily[].tmax number Maximum temperature °C.
daily[].tmean number Mean temperature °C.
daily[].precipMm number Total precipitation mm.
daily[].snowMm number Snow mm (approx. water equivalent).
daily[].windKmh number Max wind km/h.
daily[].windGustKmh number Max wind gust km/h. For past days from ERA5 (0.25° grid, daily max of end-of-hour hourly gusts); may be lower than mean wind (windKmh, 0.1° ERA5-Land). May be null.
daily[].windDirectionDeg number Dominant wind direction degrees.
daily[].humidityPercent number Mean relative humidity %.
daily[].pressureHpa number Mean pressure hPa.
daily[].cloudPercent number Mean cloud cover %. May be null.
daily[].uvi number Max UV index (forecast only).
daily[].dewPointC number Mean dew point °C.
daily[].et0Mm number Reference evapotranspiration ET0 mm (FAO-56).
daily[].sunrise string Sunrise UTC ISO.
daily[].sunset string Sunset UTC ISO.
daily[].daylightMinutes integer Daylight duration minutes.
daily[].weatherCode integer OpenWeather-style condition code (800 clear, 5xx rain ...).
hourly array Hourly rows when granularity is hourly/both.
hourly[].time string Hour UTC ISO.
hourly[].tempC number Temperature °C.
hourly[].humidityPercent number Relative humidity %.
hourly[].windKmh number Wind km/h.
hourly[].windGustKmh number Wind gust km/h (max gust over the preceding hour). May be null.
hourly[].precipMm number Precipitation in that hour mm.
hourly[].precipProbability number Precipitation probability 0–1 (when available).
hourly[].cloudPercent number Cloud cover %. May be null.
hourly[].weatherCode integer OpenWeather-style condition code.
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,
    "granularity": "daily",
    "fromDate": "2026-06-01",
    "toDate": "2026-06-03",
    "daysTotal": 3,
    "daysWithData": 3,
    "hoursWithData": 0,
    "missingCount": 0,
    "missingDates": [],
    "daily": [
      {
        "date": "2026-06-01",
        "tmin": 14.2,
        "tmax": 27.9,
        "tmean": 20.8,
        "precipMm": 0.0,
        "windKmh": 11.5,
        "humidityPercent": 46.0,
        "et0Mm": 5.10,
        "weatherCode": 800
      },
      {
        "date": "2026-06-02",
        "tmin": 15.0,
        "tmax": 29.1,
        "tmean": 21.6,
        "precipMm": 1.2,
        "windKmh": 13.0,
        "humidityPercent": 52.0,
        "et0Mm": 5.44,
        "weatherCode": 500
      }
    ],
    "hourly": [],
    "sources": [
      "open-meteo"
    ],
    "disclaimer": "Weather data aggregated 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/weather/history', {
        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/weather/history', 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/weather/history");
      Console.WriteLine(response);
  
  
      $response = file_get_contents('https://api.apikodu.com/api/v1/weather/history', 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/weather/history' \
        -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