API Documentation

  • ✨ API Version 2 — Expanded station support (30 stations), metric units for international locations, Wethr Low calculations, and explicit logic parameters. Base URL: https://wethr.net/api/v2/

    Introduction

    The Wethr.net API v2 provides programmatic access to weather observation data and model forecasts. It includes support for 30 weather stations across the US and international markets, with native metric units for non-US stations.

    Base URL: https://wethr.net/api/v2/


    What's New in v2

    • Push API BETA: Stream real-time observations, DSM/CLI releases, and temperature extreme alerts
    • Precipitation API BETA: New endpoint for monthly precipitation totals with real-time ASOS data
    • NWS Forecasts API BETA: New endpoint for NWS hourly temperature forecasts with version history
    • Expanded Station Support: 30 stations including London, Buenos Aires, Toronto, and Seoul
    • Metric Units: International stations (EGLC, SAEZ, CYYZ, RKSI, NZWN, SBGR, LFPG, LTAC) return temperatures in Celsius
    • Wethr Low: The wethr_high mode now also returns wethr_low
    • Improved Wethr High/Low Accuracy (NWS mode): NWS logic incorporates high-frequency observations to capture extremes between standard METAR reporting intervals. WU/Polymarket logic uses only standard METAR observations.
    • Required Logic Parameter: Explicit logic parameter required for wethr_high mode (nws or wu)
    • Observation Type Filter: Filter latest mode by dsm_high, dsm_low, cli_high, cli_low
    • Units Indicator: All responses include a units field

    Authentication

    All requests require an API key. Include it in the HTTP header:

    Authorization: Bearer <YOUR_API_KEY>

    Or use the custom header:

    X-API-Key: <YOUR_API_KEY>

    Generate API keys in your Account Settings.


    Rate Limiting

    TierRequests/MinuteRequests/Day
    Professional605,000
    Developer30050,000
    Enterprise30050,000

    Supported Stations

    US Stations (Fahrenheit)

    CodeLocationTimezone
    KMDWChicago MidwayAmerica/Chicago
    KPHLPhiladelphiaAmerica/New_York
    KMIAMiamiAmerica/New_York
    KLAXLos AngelesAmerica/Los_Angeles
    KBKFAurora (Buckley SFB)America/Denver
    KDENDenverAmerica/Denver
    KAUSAustinAmerica/Chicago
    KNYCNew York (Central Park)America/New_York
    KDFWDallas/Fort WorthAmerica/Chicago
    KMSYNew OrleansAmerica/Chicago
    KLGANew York LaGuardiaAmerica/New_York
    KDALDallas Love FieldAmerica/Chicago
    KHOUHouston HobbyAmerica/Chicago
    KSEASeattleAmerica/Los_Angeles
    KSFOSan FranciscoAmerica/Los_Angeles
    KLASLas VegasAmerica/Los_Angeles
    KPHXPhoenixAmerica/Phoenix
    KSATSan AntonioAmerica/Chicago
    KDCAWashington D.C.America/New_York
    KCLTCharlotteAmerica/New_York
    KBOSBostonAmerica/New_York
    KBNANashvilleAmerica/Chicago
    KATLAtlantaAmerica/New_York
    KJAXJacksonvilleAmerica/New_York
    KOKCOklahoma CityAmerica/Chicago
    KDTWDetroitAmerica/Detroit
    KMSPMinneapolisAmerica/Chicago

    International Stations (Celsius) NEW

    CodeLocationTimezone
    EGLCLondon City AirportEurope/London
    SAEZBuenos Aires EzeizaAmerica/Argentina/Buenos_Aires
    CYYZToronto PearsonAmerica/Toronto
    RKSISeoul IncheonAsia/Seoul
    SBGRSão Paulo GuarulhosAmerica/Sao_Paulo
    LFPGParis Charles de GaulleEurope/Paris
    LTACEsenboğa International AirportEurope/Istanbul

    Error Responses

    • 400 Bad Request — Invalid or missing parameters
    • 401 Unauthorized — Invalid or missing API key
    • 429 Too Many Requests — Rate limit exceeded
    • 500 Server Error — Internal server error
    {
        "error": "Missing required parameter: logic",
        "details": "The 'logic' parameter is required for wethr_high mode. Valid values: 'nws' or 'wu'."
    }

    Observations API

    GET /api/v2/observations.php

    Mode: Latest Observation

    Returns the most recent observation for a station.

    Parameters

    ParameterRequiredDescription
    station_codeYesStation identifier
    modeYesSet to latest
    observation_typeNoFilter: dsm_high, dsm_low, cli_high, cli_low

    Example Request

    GET /api/v2/observations.php?station_code=KMDW&mode=latest
    GET /api/v2/observations.php?station_code=KMDW&mode=latest&observation_type=cli_high

    Example Response

    {
        "station_code": "KMDW",
        "observation_time": "2025-06-15 18:53:00",
        "temperature": 26.7,
        "temperature_display": 80.1,
        "lowest_probable": 80,
        "highest_probable": 80,
        "units": "fahrenheit",
        "dsm_high": 28.3,
        "dsm_high_display": 83,
        "relative_humidity": 55.2
    }

    Mode: Wethr High/Low Calculation

    Calculates the current trading-day high and low temperatures based on multiple observation sources.

    • NWS logic: Uses CLI/DSM reports, 6-hour highs/lows, and all available observations to capture extremes between standard reporting intervals. Time window follows Standard Time year-round.
    • WU logic: Uses only standard METAR observations. Time window follows Local Time year-round.

    Parameters

    ParameterRequiredDescription
    station_codeYesStation identifier
    modeYesSet to wethr_high
    logic Yes nws — NWS/Kalshi: Standard Time year-round, uses CLI/DSM/6hr data
    wu — Weather Underground: Local Time year-round, uses exact temperature

    Example Request

    GET /api/v2/observations.php?station_code=KMDW&mode=wethr_high&logic=nws

    Example Response

    {
        "station_code": "KMDW",
        "date": "2025-06-15",
        "wethr_high": 83,
        "wethr_low": 68,
        "time_of_high_utc": "2025-06-15 20:53:00",
        "time_of_low_utc": "2025-06-15 10:53:00",
        "calculation_logic": "nws",
        "units": "fahrenheit"
    }

    Mode: History

    Retrieves observations over a time range (max 24 hours). Default mode when mode is omitted.

    Parameters

    ParameterRequiredDescription
    station_codeYesStation identifier
    start_timeYesStart of range (ISO 8601 UTC)
    end_timeYesEnd of range (ISO 8601 UTC)

    Example Request

    GET /api/v2/observations.php?station_code=KMDW&start_time=2025-06-15T00:00:00Z&end_time=2025-06-15T12:00:00Z

    Observation Data Model

    FieldTypeDescription
    idintegerUnique record identifier
    station_codestringStation identifier
    observation_timedatetimeUTC timestamp
    temperaturedecimalTemperature in Celsius (raw)
    temperature_displaydecimalTemperature in station's native units
    lowest_probableintegerMin probable temp (native units)
    highest_probableintegerMax probable temp (native units)
    unitsstringfahrenheit or celsius
    precision_levelintegerData precision (1 = exact)
    dew_pointdecimalDew point (Celsius)
    relative_humiditydecimalRelative humidity (%)
    wind_directionstringWind direction
    wind_speeddecimalWind speed (knots)
    wind_gustdecimalWind gust (knots)
    visibilitydecimalVisibility (statute miles)
    six_hour_highdecimal6-hour high (Celsius)
    six_hour_lowdecimal6-hour low (Celsius)
    cli_high / cli_lowdecimalCLI report values (US only)
    dsm_high / dsm_lowdecimalDSM report values (US only)
    *_displayintegerValues in station's native units
    *_fintegerValues in Fahrenheit (backward compat)

    Client Examples

    cURL — Wethr High with NWS Logic

    curl -G "https://wethr.net/api/v2/observations.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KMDW" \
      --data-urlencode "mode=wethr_high" \
      --data-urlencode "logic=nws"

    cURL — Latest CLI High

    curl -G "https://wethr.net/api/v2/observations.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KMDW" \
      --data-urlencode "mode=latest" \
      --data-urlencode "observation_type=cli_high"

    JavaScript — Wethr High/Low

    const params = new URLSearchParams({
        station_code: 'KMDW',
        mode: 'wethr_high',
        logic: 'nws'
    });
    
    fetch(`/api/v2/observations.php?${params}`, {
        headers: { 'Authorization': `Bearer ${apiKey}` }
    })
    .then(res => res.json())
    .then(data => {
        console.log(`High: ${data.wethr_high}° / Low: ${data.wethr_low}°`);
    });

    Python — Latest Observation

    import requests
    
    response = requests.get(
        'https://wethr.net/api/v2/observations.php',
        params={'station_code': 'KMDW', 'mode': 'latest'},
        headers={'Authorization': f'Bearer {api_key}'}
    )
    data = response.json()
    print(f"Current: {data['temperature_display']}°{data['units'][0].upper()}")

    Forecasts API

    GET /api/v2/forecasts.php

    Retrieves model forecast data for a location within a time range.

    Parameters

    ParameterRequiredDescription
    location_nameYesLocation identifier (e.g., KMDW)
    start_valid_timeYesStart of forecast range (ISO 8601)
    end_valid_timeYesEnd of forecast range (ISO 8601)
    model No Filter by model: ARPEGE, ECMWF-IFS, GEFS, GEM-GDPS, GEM-HRDPS, GFS, GFS-MOS, HRRR, ICON, JMA, LAV-MOS, NAM, NAM-MOS, NAM4KM, NBM, NBS-MOS, RAP, UKMO

    Example Request

    GET /api/v2/forecasts.php?location_name=KMDW&start_valid_time=2025-06-15T18:00:00Z&end_valid_time=2025-06-15T20:00:00Z&model=HRRR

    Forecast Data Model

    FieldTypeDescription
    idintegerUnique record identifier
    modelstringForecast model name
    location_namestringLocation identifier
    latitudedecimalLatitude
    longitudedecimalLongitude
    run_timedatetimeModel run time (UTC)
    valid_timedatetimeForecast valid time (UTC)
    forecast_hourintegerLead time in hours
    temperature_kdecimalTemperature (Kelvin)
    temperature_fdecimalTemperature (Fahrenheit)
    temperature_cdecimalTemperature (Celsius)

    Precipitation API BETA

    GET /api/v2/precipitation.php
    ⚠️ Beta Notice: This API is currently in beta testing. While functional, you may encounter bugs or unexpected behavior. Data accuracy is not guaranteed during this phase. Please report any issues to help us improve the service.

    Returns current month precipitation totals for a station, combining official CLI (Climate Report) data with live ASOS observations. All date/time calculations use Local Standard Time (no DST adjustment) year-round, matching NWS climate reporting standards.

    Endpoint & Parameters

    ParameterRequiredDescription
    station_codeYesStation identifier (see supported stations below)

    Note: This endpoint always returns data for the current month. Historical month data is not available via this API.

    Supported Stations

    KNYC, KLAX, KMDW, KSFO, KAUS, KMIA, KDFW, KHOU, KDEN, KBKF, KSEA, KPHL, KLAS, KPHX, KSAT, KDCA, KCLT, KBOS, KBNA, KATL, KJAX, KOKC, KDTW, KMSP, KMSY

    Example Request

    GET /api/v2/precipitation.php?station_code=KAUS

    Example Response

    {
        "station_code": "KAUS",
        "station_name": "Austin",
        "timezone": "America/Chicago",
        "timezone_offset_hours": -6,
        "today_local_date": "2025-06-15",
        "month": 6,
        "year": 2025,
        "official_mtd": 1.45,
        "today_precip": 0.127,
        "total_mtd": 1.58,
        "has_trace": false,
        "last_trace_time": null,
        "cli_date": "2025-06-14",
        "cli_issued_at": "2025-06-15 05:15:00",
        "today_hourly_max": {
            "2025-06-15 08": 0.05,
            "2025-06-15 09": 0.077
        },
        "timestamp": "2025-06-15T21:30:00Z",
        "units": "inches"
    }

    Response Fields

    FieldTypeDescription
    station_codestringStation identifier
    station_namestringHuman-readable station name
    timezonestringPHP timezone identifier
    timezone_offset_hoursintegerFixed UTC offset for Local Standard Time (e.g., -6 for CST)
    today_local_datestringCurrent date in station's Local Standard Time (YYYY-MM-DD)
    monthintegerCurrent month (1-12)
    yearintegerCurrent year
    official_mtddecimalOfficial month-to-date total from CLI reports (through yesterday)
    today_precipdecimalToday's precipitation calculated from live ASOS observations
    total_mtddecimalCombined total: official_mtd + today_precip
    has_tracebooleanWhether trace precipitation (P0000) was reported today
    last_trace_timestring|nullTime of last trace report (Local Standard Time)
    cli_datestring|nullDate of the most recent CLI report used
    cli_issued_atstring|nullTimestamp when the CLI report was issued
    today_hourly_maxobjectHourly precipitation breakdown for today (hour → max precip)
    timestampstringAPI response timestamp (UTC, ISO 8601)
    unitsstringAlways inches

    Understanding the Data

    • Official (CLI): The official_mtd value comes from the NWS Daily Climate Report (CLI), typically issued around 5 AM local time. This is the "banked" official total through the previous day.
    • Live (Today): The today_precip value is calculated in real-time from 5-minute ASOS observations since midnight Local Standard Time.
    • Trace: When has_trace is true, precipitation was detected but was too small to measure (<0.01"). Trace amounts are not included in the totals.
    • Hourly Max: The today_hourly_max object shows the maximum cumulative reading for each hour, useful for detailed analysis.

    cURL Example

    curl -G "https://wethr.net/api/v2/precipitation.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KAUS"

    Python Example

    import requests
    
    response = requests.get(
        'https://wethr.net/api/v2/precipitation.php',
        params={'station_code': 'KAUS'},
        headers={'Authorization': f'Bearer {api_key}'}
    )
    data = response.json()
    
    print(f"Month-to-Date: {data['total_mtd']}\"")
    print(f"  Official (CLI): {data['official_mtd']}\"")
    print(f"  Today (Live):   {data['today_precip']}\"")
    if data['has_trace']:
        print(f"  Trace detected at {data['last_trace_time']}")

    NWS Forecasts API BETA

    GET /api/v2/nws_forecasts.php
    ⚠️ Beta Notice: This API is currently in beta testing. While functional, you may encounter bugs or unexpected behavior. Please report any issues to help us improve the service.

    Returns NWS hourly temperature forecasts for a station. Forecasts are sourced from the National Weather Service API and stored with version tracking as they update throughout the day.

    ⚠️ Critical: Local Standard Time Convention
    All dates and hours in this API use Local Standard Time year-round (no Daylight Saving Time adjustment). This means:
    • During DST months, the "day" boundaries are shifted by 1 hour compared to civil time
    • Hour 0 always represents midnight Standard Time, not midnight local civil time
    • This convention matches NWS climate reporting and Kalshi temperature market resolution

    If you are using a different resolution source that uses civil time (with DST), these forecasts may not align correctly with your day boundaries.

    Endpoint & Parameters

    ParameterRequiredDescription
    station_codeYesStation identifier
    date No Forecast date in YYYY-MM-DD format. Defaults to today. Can request up to 2 days in the future or 365 days (1 year) in the past.
    mode No latest (default) — Returns only the most recent forecast version for the requested date
    history — Returns all forecast versions for the requested date (useful to see how the forecast evolved)

    Example Requests

    # Today's latest forecast
    GET /api/v2/nws_forecasts.php?station_code=KAUS
    
    # Tomorrow's latest forecast
    GET /api/v2/nws_forecasts.php?station_code=KAUS&date=2025-06-16
    
    # Today's forecast history (all versions)
    GET /api/v2/nws_forecasts.php?station_code=KAUS&date=2025-06-15&mode=history

    Example Response (mode=latest)

    {
        "station_code": "KAUS",
        "station_name": "Austin",
        "timezone": "America/Chicago",
        "timezone_offset_hours": -6,
        "forecast_date": "2025-06-15",
        "version": 12,
        "hourly_temps": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 94, 95, 95, 94, 92, 89, 85, 82, 79, 77, 75],
        "high": 95,
        "low": 75,
        "timestamp": "2025-06-15T21:30:00Z",
        "units": "fahrenheit",
        "time_convention": "local_standard_time"
    }

    Example Response (mode=history)

    {
        "station_code": "KAUS",
        "station_name": "Austin",
        "timezone": "America/Chicago",
        "timezone_offset_hours": -6,
        "forecast_date": "2025-06-15",
        "total_versions": 3,
        "forecasts": [
            {
                "version": 1,
                "hourly_temps": [null, null, null, null, null, null, 71, 74, 78, 82, ...],
                "high": 94,
                "low": 71
            },
            {
                "version": 2,
                "hourly_temps": [null, null, null, null, null, null, null, null, null, null, null, null, 91, 93, ...],
                "high": 95,
                "low": 77
            }
        ],
        "timestamp": "2025-06-15T21:30:00Z",
        "units": "fahrenheit",
        "time_convention": "local_standard_time"
    }

    Response Fields

    FieldTypeDescription
    station_codestringStation identifier
    station_namestringHuman-readable station name
    timezonestringPHP timezone identifier
    timezone_offset_hoursintegerFixed UTC offset for Local Standard Time
    forecast_datestringForecast date (YYYY-MM-DD) in Local Standard Time
    versionintegerForecast version number (latest mode only)
    hourly_tempsarrayArray of 25 temperatures (indices 0-24, where 24 = midnight next day). Values are null for hours that had already passed when the forecast was issued.
    highinteger|nullForecasted high temperature, calculated as the maximum of all non-null values in hourly_temps
    lowinteger|nullForecasted low temperature, calculated as the minimum of all non-null values in hourly_temps
    total_versionsintegerNumber of forecast versions available (history mode only)
    forecastsarrayArray of all forecast versions (history mode only)
    unitsstringAlways fahrenheit
    time_conventionstringAlways local_standard_time

    Understanding the Time Convention

    The hourly_temps array contains 25 values representing hours 0 through 24:

    • Index 0: Midnight (00:00) Local Standard Time
    • Index 12: Noon (12:00) Local Standard Time
    • Index 24: Midnight (00:00) next day — included for continuity

    Null Values for Past Hours

    The NWS API only provides forecasts for future hours. Hours that have already occurred when the forecast was fetched will have null values. For example, if a forecast is fetched at 2:00 PM, indices 0-13 will typically be null while indices 14-24 will contain forecasted temperatures.

    When using mode=history, earlier forecast versions will have more non-null values since they were fetched when more hours were still in the future.

    Example during Daylight Saving Time

    In Austin (CST/CDT), during summer when CDT is in effect:

    • Index 0 represents midnight Central Standard Time (which is 1:00 AM CDT civil time)
    • The "day" in this API runs from 1:00 AM to 1:00 AM civil time during DST months

    cURL Example

    curl -G "https://wethr.net/api/v2/nws_forecasts.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KAUS" \
      --data-urlencode "date=2025-06-15"

    Python Example

    import requests
    
    response = requests.get(
        'https://wethr.net/api/v2/nws_forecasts.php',
        params={'station_code': 'KAUS', 'mode': 'latest'},
        headers={'Authorization': f'Bearer {api_key}'}
    )
    data = response.json()
    
    print(f"Forecast for {data['forecast_date']} (version {data['version']})")
    print(f"High: {data['high']}°F / Low: {data['low']}°F")
    print(f"Hourly: {data['hourly_temps']}")

    Push API BETA

    ⚠️ Beta Product: The Push API is currently in beta. While we strive to maintain high availability and data quality, this service may undergo changes without notice. Additionally, weather data is sourced from upstream providers (NOAA, NWS, Synoptic) and station sensors that may occasionally experience outages or report erroneous values. We strongly recommend implementing your own data validation logic to detect and handle anomalies such as unrealistic temperature spikes, sensor malfunctions, or missing data. Wethr.net is not liable for trading decisions or other actions based on data received through this API.

    Overview

    The Push API delivers real-time weather data as events occur. Instead of polling the REST API, clients maintain a persistent connection and receive updates instantly — including new observations, DSM/CLI releases, and temperature extreme alerts.

    Key Benefits:
    • Real-time updates with sub-second latency
    • Efficient — no polling overhead
    • Automatic reconnection with event replay
    • Temperature alerts for new highs/lows as they occur

    Base URL: https://wethr.net:3443/api/v2/stream


    Authentication & Rate Limits

    The Push API uses API key authentication. Include your key as a query parameter:

    GET https://wethr.net:3443/api/v2/stream?stations=KAUS,KMDW&api_key=YOUR_API_KEY
    TierMax StationsConnections per User
    Professional51
    DeveloperUnlimited1
    EnterpriseUnlimited1

    Requirements:

    • HTTPS only
    • One connection per user account
    • API key must be enabled in your account

    Connecting

    Parameters

    ParameterRequiredDescription
    stationsYesComma-separated station codes (e.g., KAUS,KMDW,KLAX)
    api_keyYesYour API key
    last_event_idNoResume from a specific event ID (for reconnection)

    Connection Lifecycle

    1. Client connects with station list and API key
    2. Server validates credentials and station limits
    3. Server sends connected event with subscribed stations
    4. Server streams events as they occur
    5. Server sends periodic heartbeat events (every 30s)
    6. On disconnect, client can reconnect with last_event_id to replay missed events

    Event Types

    EventDescriptionFrequency
    connectedConnection establishedOnce on connect
    heartbeatKeep-alive signalEvery 30 seconds
    observationNew weather observation (METAR/HF-METAR/SPECI)Every 1-5 minutes per station
    dsmDaily Summary Message releasedVaries by station
    cliClimate Report releasedVaries by station
    new_highNew temperature high detectedAs conditions change
    new_lowNew temperature low detectedAs conditions change

    Payload Reference

    observation

    Sent when a new METAR, HF-METAR, or SPECI observation is received.

    {
        "station_code": "KAUS",
        "event": "observation",
        "timezone": "America/Chicago",
        "local_date": "2026-02-08",
        "product": "HF-METAR",
        "observation_time_utc": "2026-02-08T18:55:00Z",
        "temperature_celsius": 24,
        "temperature_fahrenheit": 75.2,
        "dew_point_celsius": 12,
        "dew_point_fahrenheit": 53.6,
        "relative_humidity": 47,
        "wind_direction": "200",
        "wind_speed_mph": 14,
        "wind_speed_kmh": 22,
        "wind_gust_mph": null,
        "wind_gust_kmh": null,
        "visibility_miles": 10,
        "altimeter_inhg": 30.12,
        "wethr_high": {
            "nws": {"value_f": 75, "value_c": 24, "time_utc": "2026-02-08T18:44:00Z"},
            "wu": {"value_f": 73, "value_c": 23, "time_utc": "2026-02-08T17:53:00Z"}
        },
        "wethr_low": {
            "nws": {"value_f": 42, "value_c": 6, "time_utc": "2026-02-08T12:53:00Z"},
            "wu": {"value_f": 42, "value_c": 6, "time_utc": "2026-02-08T12:53:00Z"}
        },
        "high_valid_through_utc": "2026-02-08T18:00:00Z",
        "low_valid_through_utc": "2026-02-08T12:00:00Z",
        "anomaly": false,
        "suspect_temperature": null,
        "id": "49500",
        "timestamp": "2026-02-08T18:56:15Z"
    }

    Note on Wethr High/Low:

    • nws: Takes into account all observations, CLI/DSM data, Standard Time window
    • wu: METAR observations only, Local Time window

    Valid Through (HVT/LVT):

    high_valid_through_utc and low_valid_through_utc indicate the time through which the high/low values are considered "locked in" based on official reports (DSM/CLI) and confirmed 6-hour extremes. A null value means the extreme is still based on preliminary observations and may change.

    Data Quality Flags:

    • anomaly and suspect_temperature help identify potentially erroneous data. See Data Quality Flags for details.

    dsm

    Sent when the Daily Summary Message is released. Timing varies by station.

    {
        "station_code": "KAUS",
        "event": "dsm",
        "for_date": "2026-02-07",
        "high_f": 84,
        "high_c": 29,
        "high_time_utc": "2026-02-07T21:53:00Z",
        "low_f": 42,
        "low_c": 6,
        "low_time_utc": "2026-02-07T12:53:00Z",
        "anomaly": false,
        "id": "49123",
        "timestamp": "2026-02-08T06:15:00Z"
    }

    cli

    Sent when the Climate Report is released. Timing varies by station.

    {
        "station_code": "KAUS",
        "event": "cli",
        "for_date": "2026-02-07",
        "high_f": 84,
        "high_c": 29,
        "low_f": 42,
        "low_c": 6,
        "anomaly": false,
        "id": "49456",
        "timestamp": "2026-02-08T14:30:00Z"
    }

    new_high / new_low

    Sent immediately when a new temperature extreme is detected.

    {
        "station_code": "KAUS",
        "event": "new_high",
        "logic": "nws",
        "value_f": 75,
        "value_c": 24,
        "prev_value_f": 73,
        "prev_value_c": 23,
        "observation_time_utc": "2026-02-08T18:44:00Z",
        "id": "49478",
        "timestamp": "2026-02-08T18:46:29Z"
    }

    The logic field indicates which calculation triggered the alert (nws or wu). You may receive separate alerts for each logic if both detect a new extreme.


    Data Quality Flags

    The Push API includes flags to help you identify potentially erroneous data. We strongly recommend checking these fields before using observation data for trading or other high-stakes decisions.

    FieldEvent(s)TypeDescription
    anomaly observation, dsm, cli boolean DSM/CLI high temperature is suspiciously elevated vs. nearby METAR observations (possible erroneous official report)
    suspect_temperature observation object | null METAR temperature failed plausibility checks. When present, temperature_celsius / temperature_fahrenheit are null. The rejected values and reason are preserved in this object. The implausible reading is excluded from all calculations — it will not affect wethr_high, wethr_low, or trigger new_high / new_low alerts.

    suspect_temperature Object

    FieldTypeDescription
    raw_celsiusnumberThe rejected temperature in Celsius
    raw_fahrenheitnumberThe rejected temperature in Fahrenheit
    reasonstringMachine-readable reason code (currently: out_of_range)
    messagestringHuman-readable description

    Example: Suspect Temperature Event

    {
        "station_code": "KLAX",
        "event": "observation",
        "product": "METAR",
        "temperature_celsius": null,
        "temperature_fahrenheit": null,
        "suspect_temperature": {
            "raw_celsius": -61.0,
            "raw_fahrenheit": -77.8,
            "reason": "out_of_range",
            "message": "Temperature outside plausible range (-60°C to 60°C)"
        },
        "wethr_high": {
            "nws": {"value_f": 68, "value_c": 20, "time_utc": "2026-02-08T21:53:00Z"},
            "wu": {"value_f": 68, "value_c": 20, "time_utc": "2026-02-08T21:53:00Z"}
        },
        "anomaly": false,
        "id": "49501",
        "timestamp": "2026-02-08T22:56:15Z"
    }

    In this example, KLAX reported −61°C which is clearly erroneous. The temperature was rejected and preserved in suspect_temperature for transparency. The wethr_high and wethr_low values are unaffected, and no new_low alert was triggered.


    Client Examples

    cURL — Test Connection

    curl -N "https://wethr.net:3443/api/v2/stream?stations=KAUS,KMDW&api_key=YOUR_API_KEY"

    JavaScript (Browser)

    const apiKey = 'YOUR_API_KEY';
    const stations = ['KAUS', 'KMDW', 'KLAX'];
    
    const url = `https://wethr.net:3443/api/v2/stream?stations=${stations.join(',')}&api_key=${apiKey}`;
    const eventSource = new EventSource(url);
    
    eventSource.addEventListener('observation', (e) => {
        const data = JSON.parse(e.data);
        
        // Check for suspect temperature
        if (data.suspect_temperature) {
            console.warn(`⚠️ ${data.station_code}: Suspect temp rejected (${data.suspect_temperature.raw_fahrenheit}°F - ${data.suspect_temperature.reason})`);
            return;
        }
        
        console.log(`${data.station_code}: ${data.temperature_fahrenheit}°F`);
        console.log(`  Wethr High (NWS): ${data.wethr_high.nws.value_f}°F`);
    });
    
    eventSource.addEventListener('new_high', (e) => {
        const data = JSON.parse(e.data);
        console.log(`🔥 NEW HIGH at ${data.station_code}: ${data.value_f}°F (was ${data.prev_value_f}°F)`);
    });
    
    eventSource.addEventListener('new_low', (e) => {
        const data = JSON.parse(e.data);
        console.log(`❄️ NEW LOW at ${data.station_code}: ${data.value_f}°F (was ${data.prev_value_f}°F)`);
    });
    
    eventSource.onerror = (e) => {
        console.error('Connection error:', e);
    };

    Python

    import sseclient
    import requests
    import json
    
    api_key = 'YOUR_API_KEY'
    stations = 'KAUS,KMDW,KLAX'
    url = f'https://wethr.net:3443/api/v2/stream?stations={stations}&api_key={api_key}'
    
    response = requests.get(url, stream=True)
    client = sseclient.SSEClient(response)
    
    for event in client.events():
        if event.event == 'observation':
            data = json.loads(event.data)
            
            # Check for suspect temperature
            if data.get('suspect_temperature'):
                st = data['suspect_temperature']
                print(f"⚠️ {data['station_code']}: Suspect temp rejected ({st['raw_fahrenheit']}°F - {st['reason']})")
                continue
            
            print(f"{data['station_code']}: {data['temperature_fahrenheit']}°F")
            print(f"  Wethr High (NWS): {data['wethr_high']['nws']['value_f']}°F")
        
        elif event.event == 'new_high':
            data = json.loads(event.data)
            print(f"🔥 NEW HIGH at {data['station_code']}: {data['value_f']}°F")

    Node.js

    const EventSource = require('eventsource');
    
    const apiKey = 'YOUR_API_KEY';
    const stations = 'KAUS,KMDW,KLAX';
    const url = `https://wethr.net:3443/api/v2/stream?stations=${stations}&api_key=${apiKey}`;
    
    const es = new EventSource(url);
    
    es.addEventListener('observation', (e) => {
        const data = JSON.parse(e.data);
        console.log(`${data.station_code}: ${data.temperature_fahrenheit}°F`);
    });
    
    es.addEventListener('new_high', (e) => {
        const data = JSON.parse(e.data);
        console.log(`NEW HIGH at ${data.station_code}: ${data.value_f}°F`);
    });
    
    es.onerror = (err) => {
        console.error('Error:', err);
    };

    Reconnection with Event Replay

    If your connection drops, you can resume from where you left off using the last_event_id parameter. Track the id field from each event and pass it on reconnect:

    let lastEventId = null;
    
    function connect() {
        let url = `https://wethr.net:3443/api/v2/stream?stations=KAUS&api_key=${apiKey}`;
        if (lastEventId) {
            url += `&last_event_id=${lastEventId}`;
        }
        
        const es = new EventSource(url);
        
        es.onmessage = (e) => {
            const data = JSON.parse(e.data);
            lastEventId = data.id;  // Track for reconnection
        };
        
        es.onerror = () => {
            es.close();
            setTimeout(connect, 5000);  // Reconnect after 5s
        };
    }
    
    connect();
  • ⚠️ API Version 1 (Legacy) — This version is maintained for backward compatibility. New integrations should use API v2 for expanded features and station support. Base URL: https://wethr.net/api/v1/

    Introduction

    The Wethr.net API v1 provides access to weather observation data and model forecasts. This version supports 24 US stations with all temperatures in Fahrenheit.

    Base URL: https://wethr.net/api/v1/


    Authentication

    Include your API key in the request header:

    Authorization: Bearer <YOUR_API_KEY>

    Or:

    X-API-Key: <YOUR_API_KEY>

    Rate Limiting

    TierRequests/MinuteRequests/Day
    Professional605,000
    Developer30050,000
    Enterprise30050,000

    Error Responses

    • 400 Bad Request — Invalid parameters
    • 401 Unauthorized — Invalid API key
    • 429 Too Many Requests — Rate limit exceeded
    • 500 Server Error — Internal error

    Observations API

    GET /api/v1/observations.php

    Mode: Latest Observation

    Returns the most recent observation.

    GET /api/v1/observations.php?station_code=KMDW&mode=latest

    Example Response

    {
        "station_code": "KMDW",
        "temperature": 26.7,
        "observation_time": "2025-06-15T18:53:00Z",
        "lowest_probable_f": 80,
        "highest_probable_f": 80,
        "dsm_high_f": 83,
        "relative_humidity": 55.2
    }

    Mode: Wethr High

    Returns the calculated trading-day high. Logic is determined automatically by station type.

    GET /api/v1/observations.php?station_code=KMDW&mode=wethr_high

    Example Response

    {
        "station_code": "KMDW",
        "date": "2025-06-15",
        "wethr_high": 83,
        "time_of_high_utc": "2025-06-15 20:53:00",
        "calculation_logic": "standard"
    }

    Mode: History

    Retrieves observations over a time range (max 24 hours).

    GET /api/v1/observations.php?station_code=KMDW&start_time=2025-06-15T00:00:00Z&end_time=2025-06-15T12:00:00Z

    Observation Data Model

    FieldTypeDescription
    station_codestringStation identifier
    observation_timedatetimeUTC timestamp
    temperaturedecimalTemperature (Celsius)
    temperature_fdecimalTemperature (Fahrenheit)
    lowest_probable_fintegerMin probable temp (°F)
    highest_probable_fintegerMax probable temp (°F)
    dew_pointdecimalDew point (Celsius)
    relative_humiditydecimalRelative humidity (%)
    cli_high / cli_high_fdecimal/intCLI report high
    dsm_high / dsm_high_fdecimal/intDSM report high
    six_hour_highdecimal6-hour high (Celsius)
    wind_speeddecimalWind speed (knots)
    visibilitydecimalVisibility (miles)

    Forecasts API

    GET /api/v1/forecasts.php

    Parameters

    ParameterRequiredDescription
    location_nameYesLocation identifier
    start_valid_timeYesStart of range (ISO 8601)
    end_valid_timeYesEnd of range (ISO 8601)
    modelNoModel filter

    Available Models: ARPEGE, ECMWF-IFS, GEFS, GEM-GDPS, GEM-HRDPS, GFS, GFS-MOS, HRRR, ICON, JMA, LAV-MOS, NAM, NAM-MOS, NAM4KM, NBM, NBS-MOS, RAP, UKMO

    Example Request

    GET /api/v1/forecasts.php?location_name=KMDW&start_valid_time=2025-06-15T18:00:00Z&end_valid_time=2025-06-15T20:00:00Z&model=HRRR

    Forecast Data Model

    FieldTypeDescription
    modelstringModel name
    location_namestringLocation
    run_timedatetimeModel run time
    valid_timedatetimeForecast valid time
    forecast_hourintegerLead time (hours)
    temperature_kdecimalTemp (Kelvin)
    temperature_fdecimalTemp (Fahrenheit)
    temperature_cdecimalTemp (Celsius)

    Client Examples

    cURL — Latest Observation

    curl -G "https://wethr.net/api/v1/observations.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KMDW" \
      --data-urlencode "mode=latest"

    cURL — Wethr High

    curl -G "https://wethr.net/api/v1/observations.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KMDW" \
      --data-urlencode "mode=wethr_high"

    cURL — History

    curl -G "https://wethr.net/api/v1/observations.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "station_code=KMDW" \
      --data-urlencode "start_time=2025-06-15T00:00:00Z" \
      --data-urlencode "end_time=2025-06-15T12:00:00Z"

    cURL — Forecasts

    curl -G "https://wethr.net/api/v1/forecasts.php" \
      -H "Authorization: Bearer <YOUR_API_KEY>" \
      --data-urlencode "location_name=KMDW" \
      --data-urlencode "start_valid_time=2025-06-15T18:00:00Z" \
      --data-urlencode "end_valid_time=2025-06-15T20:00:00Z" \
      --data-urlencode "model=HRRR"
Top