API Documentation

Programmatic access to near real-time METAR-sourced weather station data, predictions, and historical observations.

All values use metric units — temperatures in °C, wind in km/h, pressure in hPa, precipitation in mm. Timestamps are station-local (each response includes a timezone field); dates are YYYY-MM-DD. Nullable fields return null when data is unavailable.

Authentication

All API endpoints require a Pro plan and a valid API key. Generate keys from your Account page.

Include your key in the Authorization header:

curl -H "Authorization: Bearer dh_live_xxxxx" \
  https://dailyhigh.app/api/v1/stations

Keys are prefixed with dh_live_. Store them securely — you can create up to 5 active keys and revoke them at any time.

Rate Limits

Rate limits are applied per API key using a sliding 60-second window. Every response includes these headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetSeconds until the window resets
Retry-AfterOnly on 429 — seconds to wait before retrying
EndpointLimitCache TTL
/api/v1/weather/:icao120 req/min~15 s
/api/v1/stations30 req/min1 h (static metadata)
/api/v1/prediction/:icao60 req/min~2 min (30 min stale)
/api/v1/history/:icao/:date60 req/min15 s (today) · 1 h (past)

Endpoints

GET/api/v1/stations30 req/min

Returns metadata for every tracked METAR-reporting station, identified by 4-letter ICAO airport codes. Codes are uppercase in responses but accepted case-insensitively in requests. Use this endpoint to discover all available stations before calling other endpoints.

Example Request
curl -H "Authorization: Bearer dh_live_xxxxx" \
  https://dailyhigh.app/api/v1/stations
Response
{
  "ok": true,
  "data": [
    {
      "icao": "EGLC",
      "name": "London",
      "country": "gb",
      "timezone": "Europe/London",
      "region": "maritime",
      "latitude": 51.505,
      "longitude": 0.055,
      "elevation": 5.8,
      "peakHour": 15
    }
  ]
}
Response Fields — data
FieldTypeDescription
icaostringICAO airport code identifying the weather station (e.g. "EGLC").
namestringHuman-readable station/city name (e.g. "London").
countrystringTwo-letter ISO 3166-1 country code, lowercase (e.g. "gb").
timezonestringIANA timezone of the station (e.g. "Europe/London"). Use this to interpret any local timestamps.
regionstringClimate region classification. One of: "desert", "coastal", "continental", "maritime", "tropical".
latitudenumberStation latitude in decimal degrees (WGS-84). Positive = north.
longitudenumberStation longitude in decimal degrees (WGS-84). Positive = east.
elevationnumber | nullStation elevation above mean sea level in metres.
peakHournumberTypical hour (0–23, local time) when the daily maximum temperature occurs. Seasonally adjusted ±0.5 h.
GET/api/v1/weather/:icao120 req/min

Comprehensive current weather for a single station, sourced from METAR observations. Includes full atmospheric observation, today's observed extremes, sun times, station metadata, and today's forecast. Data is cached for ~15 seconds — polling faster returns the same snapshot.

Path / Query Parameters
FieldTypeDescription
:icaostringICAO airport code, case-insensitive (e.g. "EGLC" or "eglc").
Example Request
curl -H "Authorization: Bearer dh_live_xxxxx" \
  https://dailyhigh.app/api/v1/weather/EGLC
Response
{
  "ok": true,
  "data": {
    "icao": "EGLC",
    "name": "London",
    "country": "gb",
    "timezone": "Europe/London",
    "region": "maritime",
    "latitude": 51.505,
    "longitude": 0.055,
    "elevation": 5.8,
    "peakHour": 15,
    "temperature": 8.2,
    "feelsLike": 6.1,
    "dewPoint": 4.3,
    "humidity": 72,
    "windSpeed": 15,
    "windGust": 24,
    "windDirection": "SW",
    "windDirectionDeg": 220,
    "pressure": 1018.5,
    "pressureTrend": "Falling",
    "visibility": 14.0,
    "uvIndex": 2,
    "uvDescription": "Low",
    "cloudCover": 50,
    "cloudCeiling": 1200,
    "precip1Hour": 0,
    "precip24Hour": 2.4,
    "conditions": "Partly Cloudy",
    "icon": "⛅",
    "dayOrNight": "D",
    "observationTime": "2026-02-10T14:20:00+00:00",
    "todayMax": 9.1,
    "todayMin": 4.3,
    "tempChange24h": 1.5,
    "sunrise": "2026-02-10T07:24:00",
    "sunset": "2026-02-10T17:05:00",
    "forecast": { "maxTemp": 10, "minTemp": 3 }
  }
}
Response Fields — data
FieldTypeDescription
icaostringICAO station code.
namestringStation/city name.
countrystringISO 3166-1 country code (lowercase).
timezonestringIANA timezone. All "local" fields use this timezone.
regionstringClimate region: "desert" | "coastal" | "continental" | "maritime" | "tropical".
latitudenumberStation latitude (decimal degrees, WGS-84).
longitudenumberStation longitude (decimal degrees, WGS-84).
elevationnumber | nullElevation above MSL in metres.
peakHournumberTypical hour of daily max temperature (local time, 0–23).
temperaturenumber | nullCurrent observed air temperature in °C.
feelsLikenumber | null"Feels like" temperature in °C. Combines wind chill and heat index.
dewPointnumber | nullDew point temperature in °C.
humiditynumber | nullRelative humidity percentage (0–100).
windSpeednumber | nullSustained wind speed in km/h.
windGustnumber | nullWind gust speed in km/h. Null if no gust reported.
windDirectionstring | nullCardinal wind direction (e.g. "NW", "SSE").
windDirectionDegnumber | nullWind direction in degrees (0–360, 0 = north, clockwise).
pressurenumber | nullMean sea-level pressure (QNH) in hPa (mbar). Comparable across stations regardless of elevation.
pressureTrendstring | nullPressure trend: "Rising", "Falling", or "Steady".
visibilitynumber | nullHorizontal visibility in km.
uvIndexnumber | nullUV index (0–11+). Null during nighttime hours — check dayOrNight to distinguish.
uvDescriptionstring | nullUV severity label (e.g. "Low", "Moderate", "High", "Very High", "Extreme").
cloudCovernumber | nullCloud cover percentage (0–100).
cloudCeilingnumber | nullCloud ceiling height in metres. Null if sky is clear.
precip1Hournumber | nullPrecipitation in the last 1 hour in mm.
precip24Hournumber | nullPrecipitation in the last 24 hours in mm.
conditionsstring | nullHuman-readable weather condition (e.g. "Partly Cloudy", "Light Rain").
iconstringWeather emoji derived from current conditions (e.g. "☀️", "🌧️", "☁️", "❄️"). Day/night aware: clear skies return "🌙" after dark.
dayOrNightstring | null"D" for day, "N" for night, based on local sunrise/sunset.
observationTimestringISO 8601 timestamp with UTC offset (e.g. "2026-02-10T14:20:00+00:00"). Use the timezone field for local conversion.
todayMaxnumber | nullHighest observed temperature today in °C. Resets at local midnight; may be null early morning before the first observation.
todayMinnumber | nullLowest observed temperature today in °C. Resets at local midnight; may be null early morning before the first observation.
tempChange24hnumber | nullTemperature change vs. 24 hours ago in °C. Positive = warmer.
sunrisestring | nullToday's sunrise in station-local time (no offset suffix). Use the timezone field to interpret.
sunsetstring | nullToday's sunset in station-local time (no offset suffix). Use the timezone field to interpret.
forecastobject | nullToday's forecast. Null if unavailable.
Nested — forecast
FieldTypeDescription
forecast.maxTempnumberForecasted daily maximum temperature in °C.
forecast.minTempnumberForecasted daily minimum temperature in °C.
GET/api/v1/prediction/:icao60 req/min

Today's daily-high temperature prediction with confidence score and reasoning. Re-computed every ~2 minutes. Returns 202 if not yet available this cycle (retry after 30 s). A top-level 'stale: true' flag means data is from a previous cycle (up to 30 min old) while a fresh prediction is being computed.

Path / Query Parameters
FieldTypeDescription
:icaostringICAO airport code, case-insensitive.
Example Request
curl -H "Authorization: Bearer dh_live_xxxxx" \
  https://dailyhigh.app/api/v1/prediction/EGLC
Response
{
  "ok": true,
  "data": {
    "currentTemp": 8.2,
    "observedMax": 9.1,
    "predictedMax": 10.3,
    "forecastMax": 10.0,
    "modelMax": 10.1,
    "climoMax": 9.5,
    "confidence": 7,
    "predictionReason": "Warming trend",
    "reasoning": [
      "About 4h until peak warming",
      "Temperatures still climbing",
      "Observed temps tracking close to prediction"
    ],
    "isPastPeak": false,
    "hoursUntilPeak": 3.5,
    "slope": 1.2,
    "slopeWindow": "90 min"
  }
}
Response Fields — data
FieldTypeDescription
currentTempnumberCurrent temperature at the station in °C.
observedMaxnumberHighest temperature observed so far today in °C.
predictedMaxnumberDailyHigh's prediction for today's maximum temperature in °C. Updated every ~2 minutes using the latest observations and near real-time trajectory.
forecastMaxnumberThird-party forecast max for today in °C.
modelMaxnumber | nullNumerical weather model max in °C, bias-corrected for the station.
climoMaxnumber | nullClimatological average daily high for this date and station in °C.
confidencenumberConfidence score from 1 (low) to 10 (high). Rises through the day as more observations arrive and models converge.
predictionReasonstringShort one-line summary of the prediction logic (e.g. "Warming trend", "Near peak").
reasoningstring[]Array of human-readable reasoning lines with emoji prefixes, explaining the prediction factors.
isPastPeakbooleanWhether the station has likely passed its daily temperature peak. Based on solar noon and the temperature trajectory.
hoursUntilPeaknumberEstimated hours remaining until the daily temperature peak. 0 if past peak. Uses station-local solar time.
slopenumber | nullTemperature rate of change in °C/hour over the last 90 minutes. Positive = warming, negative = cooling.
slopeWindowstring | nullDescription of the window used for slope calculation (e.g. "90 min").
GET/api/v1/history/:icao/:date60 req/min

Hourly weather observations for a station on a specific date. Returns the full 24-hour profile with max/min summary and sun times.

Path / Query Parameters
FieldTypeDescription
:icaostringICAO airport code, case-insensitive.
:datestringCalendar date in YYYY-MM-DD format, in the station's local timezone. Use today's date for live intra-day data.
Example Request
curl -H "Authorization: Bearer dh_live_xxxxx" \
  https://dailyhigh.app/api/v1/history/EGLC/2026-02-09
Response
{
  "ok": true,
  "data": {
    "date": "2026-02-09",
    "icao": "EGLC",
    "name": "London City",
    "timezone": "Europe/London",
    "maxTemp": 9.8,
    "minTemp": 3.2,
    "sunrise": "2026-02-09T07:24:00",
    "sunset": "2026-02-09T17:05:00",
    "forecast": { "maxTemp": 10, "minTemp": 3 },
    "hourly": [
      {
        "time": "2026-02-09T00:00:00",
        "temperature": 4.1,
        "conditions": "Clear",
        "humidity": 85,
        "windSpeed": 8
      }
    ]
  }
}
Response Fields — data
FieldTypeDescription
datestringThe requested date in YYYY-MM-DD format (station-local calendar date).
icaostringICAO station code.
namestringStation name.
timezonestringIANA timezone of the station. All times in the hourly array are in this timezone.
maxTempnumber | nullObserved daily maximum temperature in °C for the requested date.
minTempnumber | nullObserved daily minimum temperature in °C for the requested date.
sunrisestring | nullSunrise time as an ISO 8601 string in station-local time.
sunsetstring | nullSunset time as an ISO 8601 string in station-local time.
forecastobjectThe forecast that was issued for this date.
hourlyobject[]Array of hourly observations ordered chronologically.
Nested — forecast
FieldTypeDescription
forecast.maxTempnumberForecasted daily maximum temperature in °C.
forecast.minTempnumberForecasted daily minimum temperature in °C.
Nested — hourly[]
FieldTypeDescription
hourly[].timestringISO 8601 timestamp in station-local time, without offset (e.g. "2026-02-09T14:00:00"). Aligned to whole hours.
hourly[].temperaturenumber | nullObserved temperature at this hour in °C.
hourly[].conditionsstring | nullWeather condition string (e.g. "Clear", "Overcast").
hourly[].humiditynumber | nullRelative humidity percentage (0–100).
hourly[].windSpeednumber | nullWind speed in km/h.

💡 For today's date, the hourly array grows throughout the day and is cached for ~15 seconds.

💡 For past dates, the full 24-hour array is returned and cached for 1 hour.

💡 All timestamps in the hourly array are in the station's local timezone without an offset suffix — use the top-level timezone field to interpret them.

💡 sunrise and sunset are also in station-local time.

Error Responses

Error responses use the shape { "error": "Human-readable message" }. The HTTP status code indicates the error category:

StatusMeaningWhen
202AcceptedPrediction not yet cached — retry in 30 s (prediction endpoint only)
400Bad RequestInvalid date format or malformed parameters
401UnauthorizedMissing / invalid API key, or account is not on the Pro plan
404Not FoundICAO code does not match a tracked station
429Too Many RequestsRate limit exceeded — check Retry-After header
500Server ErrorUpstream data source failure — safe to retry