Files
weatherfeeder/docs/integrations/events.md
2026-06-16 19:57:48 -05:00

14 KiB

Event Wire Contract

This document is the canonical JSON contract for events emitted by weatherfeeder JSON sinks, including stdout and NATS. Postgres stores the same event envelope fields in parent table columns; see Postgres integration.

Downstream consumers should read the envelope, switch on schema, and decode payload according to that schema.

Envelope

Every emitted event is a JSON object with these fields:

Field Type Required Notes
id string yes Stable event identifier. Treat as opaque.
kind string yes Routing kind, such as observation or alert.
source string yes Configured source name.
emitted_at timestamp yes When the daemon emitted the event.
effective_at timestamp no Timestamp the payload is about, when known.
schema string no Schema identifier. Weatherfeeder sources and normalizers set this.
payload object, array, string, or scalar yes Schema-specific payload.

Timestamps are JSON strings using Go time.Time JSON encoding, which is RFC3339Nano-compatible. Weatherfeeder normalizers use UTC timestamps for canonical payloads.

Kinds And Schemas

Canonical schemas emitted after normalization:

Kind Schema Payload
observation weather.observation.v1 WeatherObservation
forecast weather.forecast.v1 WeatherForecastRun
forecast_discussion weather.forecast_discussion.v1 WeatherForecastDiscussion
weather_story weather.weather_story.v1 WeatherStoryRun
alert weather.alert.v1 WeatherAlertRun
outlook weather.outlook.v2 WeatherOutlookRun

Raw upstream schemas emitted by current sources:

Kind Schema Payload
observation raw.nws.observation.v1 NWS observation JSON
observation raw.openmeteo.current.v1 Open-Meteo current JSON
observation raw.openweather.current.v1 OpenWeather current JSON
forecast raw.nws.hourly.forecast.v1 NWS hourly forecast JSON
forecast raw.nws.narrative.forecast.v1 NWS narrative forecast JSON
forecast_discussion raw.nws.forecast_discussion.v1 NWS forecast discussion HTML string
weather_story raw.nws.weatherstories.v1 NWS weather stories JSON
forecast raw.openmeteo.hourly.forecast.v1 Open-Meteo hourly forecast JSON
alert raw.nws.alerts.v1 NWS alerts JSON
outlook raw.spc.convective_outlook.v1 SPC convective outlook raw bundle

standards.SchemaRawOpenWeatherHourlyForecastV1 exists in code, but no current registered source emits it.

Shared Conventions

  • Canonical numeric measurements use metric units.
  • Floating-point values in canonical payloads are rounded to 4 digits after the decimal point during normalization.
  • Optional fields use JSON omitempty; absent fields should be treated as unknown.
  • conditionCode is a WMO weather interpretation code. Unknown observation conditions use -1. Forecast period conditionCode is optional.
  • Additive fields are compatible within a schema version. Removing, renaming, or changing the meaning of a field requires a new schema identifier.

weather.observation.v1

Payload type: WeatherObservation.

Field Type Required Notes
stationId string no Provider station/location identifier.
stationName string no Human station name.
timestamp timestamp yes Observation timestamp.
conditionCode integer yes WMO code; -1 means unknown.
isDay boolean no Day/night hint.
textDescription string no Short human description.
temperatureC number no Celsius.
dewpointC number no Celsius.
windDirectionDegrees number no Degrees.
windSpeedKmh number no Kilometers per hour.
windGustKmh number no Kilometers per hour.
barometricPressurePa number no Pascals.
visibilityMeters number no Meters.
relativeHumidityPercent number no Percent from 0 to 100.
apparentTemperatureC number no Celsius.
presentWeather array no Provider-specific present weather fragments.

presentWeather[] entries contain optional raw objects.

weather.forecast.v1

Payload type: WeatherForecastRun.

Field Type Required Notes
locationId string no Provider location identifier.
locationName string no Human location name.
issuedAt timestamp yes When the forecast run was generated or issued.
updatedAt timestamp no Subsequent provider update time.
product string yes Current emitted values are hourly and narrative.
latitude number no Degrees.
longitude number no Degrees.
elevationMeters number no Meters.
periods array yes Ordered forecast periods.

periods[] entries:

Field Type Required Notes
startTime timestamp yes Period start.
endTime timestamp yes Period end.
name string no Human label.
isDay boolean no Day/night hint.
conditionCode integer no WMO code when applicable.
textDescription string no Human summary.
temperatureC number no Celsius.
temperatureCMin number no Celsius.
temperatureCMax number no Celsius.
dewpointC number no Celsius.
relativeHumidityPercent number no Percent from 0 to 100.
windDirectionDegrees number no Degrees.
windSpeedKmh number no Kilometers per hour.
windGustKmh number no Kilometers per hour.
barometricPressurePa number no Pascals.
visibilityMeters number no Meters.
apparentTemperatureC number no Celsius.
cloudCoverPercent number no Percent from 0 to 100.
probabilityOfPrecipitationPercent number no Percent from 0 to 100.
precipitationAmountMm number no Liquid-equivalent millimeters.
snowfallDepthMm number no Millimeters.
uvIndex number no Unitless index.

weather.forecast_discussion.v1

Payload type: WeatherForecastDiscussion.

Field Type Required Notes
officeId string no NWS office identifier.
officeName string no Office name.
product string yes Current value is afd.
issuedAt timestamp yes Bulletin issue time.
updatedAt timestamp no Subsequent update time.
keyMessages array of strings no Extracted key messages.
shortTerm object no Short-term section.
longTerm object no Long-term section.

shortTerm and longTerm sections contain optional qualifier, issuedAt, and text fields.

weather.weather_story.v1

Payload type: WeatherStoryRun.

Field Type Required Notes
officeId string no NWS office identifier.
asOf timestamp yes Snapshot time.
stories array yes Ordered story cards.

stories[] entries:

Field Type Required Notes
officeId string no Office identifier.
startTime timestamp yes Story start.
endTime timestamp yes Story end.
updatedAt timestamp yes Story update time.
title string no Story title.
description string no Story description.
altText string no Image alternate text.
priority boolean yes Provider priority flag.
order integer yes Provider display order.
downloadUrl string no Story image URL.

weather.alert.v1

Payload type: WeatherAlertRun.

Field Type Required Notes
locationId string no Provider location identifier.
locationName string no Human location name.
asOf timestamp yes Snapshot time.
latitude number no Degrees.
longitude number no Degrees.
alerts array yes Active alerts.

alerts[] entries:

Field Type Required Notes
id string yes Provider-stable alert identifier.
event string no Alert event label.
headline string no Alert headline.
severity string no Provider severity.
urgency string no Provider urgency.
certainty string no Provider certainty.
status string no Alert status.
messageType string no Alert message type.
category string no Alert category.
response string no Recommended response.
description string no Alert description.
instruction string no Alert instruction.
sent timestamp no Provider sent time.
effective timestamp no Effective time.
onset timestamp no Alert period start.
ends timestamp no Alert period end.
expires timestamp no Provider expiration metadata; not necessarily the alert period end.
areaDescription string no Affected area description.
senderName string no Provider sender name.
references array no Related alerts.

references[] entries contain optional id, identifier, sender, and sent fields.

weather.outlook.v2

Payload type: WeatherOutlookRun.

The current producer is the SPC convective outlook normalizer. It emits Day 1-3 convective outlook snapshots for categorical, tornado, hail, and wind products that apply to the configured forecast point. Raw SPC bundles remain complete; canonical outlook payloads are filtered to local polygons. All timestamps are UTC.

Field Type Required Notes
locationId string no Operator-configured location identifier.
locationName string no Operator-configured location label.
latitude number no Configured point latitude in decimal degrees.
longitude number no Configured point longitude in decimal degrees.
asOf timestamp yes Snapshot time. For SPC, this is the latest outlook issue time when available.
issuedAt timestamp no Latest issue time across outlook features when any feature exists.
outlooks array yes Ordered outlook polygons containing the configured point.
discussions array yes Run-level day discussions for retained outlook days.

outlooks[] entries:

Field Type Required Notes
id string yes Deterministic weatherfeeder outlook identifier.
provider string yes Current value is spc.
product string yes Current value is convective.
day integer yes SPC outlook day, currently 1, 2, or 3.
outlookType string yes categorical, tornado, hail, or wind.
label string yes SPC outlook label such as SLGT or 15.
labelText string no Human label text from SPC, when present.
severityRank integer no SPC DN value, when present.
validFrom timestamp yes Valid period start.
validTo timestamp yes Valid period end.
issuedAt timestamp yes Feature issue time.
expiresAt timestamp yes Expiration time; currently equal to validTo.
forecaster string no SPC forecaster text, when present.
sourceUrl string no GeoJSON product URL for this outlook feature.
imageUrl string no Reserved for provider image URLs; currently empty.
containsLocation boolean yes Always true for emitted v2 outlooks.
geometry object yes Compact GeoJSON Polygon or MultiPolygon geometry.

geometry preserves the SPC feature geometry as compact GeoJSON using [longitude, latitude] coordinate order. containsLocation is computed with that geometry and the configured source latitude/longitude; boundary points count as contained. Polygons that do not contain the configured point are not included in canonical v2 payloads.

discussions[] entries:

Field Type Required Notes
day integer yes SPC outlook day, currently 1, 2, or 3.
headline string no Matching Day 1-3 print-page product title.
summary string no Text from the print-page ...SUMMARY... section.
discussion string no Cleaned full print-page product text.
updatedAt timestamp no Print-page update time, when present.

When no SPC polygons apply locally, the run is still emitted with outlooks: [] and discussions: []. Discussions are included only for days represented by at least one retained outlook, and multiple retained outlook types for the same day share one discussion entry.

SPC Outlook Supersession

Consumers should prefer latest-run semantics for current conditions: read the latest WeatherOutlookRun for the configured location and use its outlooks and discussions arrays together.

Historical SQL consumers that collapse older rows should identify superseded outlooks by provider, product, outlookType, validFrom, and validTo, then keep rows with the greatest issuedAt. day and label are not identity fields. When multiple retained polygons share that latest issuedAt, preserve the full group.

Legacy weather.outlook.v1

weather.outlook.v1 is a historical canonical schema retained as a standards constant for older data and consumers. Current SPC normalization emits weather.outlook.v2.

The v1 payload used WeatherOutlookRun and placed headline, summary, and discussion on each outlooks[] polygon. It also represented the pre-v2 SPC canonical behavior, where national polygons were preserved in canonical output.

Compact Example

{
  "id": "NWSObservationKSTL:2026-06-10T12:00:00Z",
  "kind": "observation",
  "source": "NWSObservationKSTL",
  "emitted_at": "2026-06-10T12:00:05Z",
  "effective_at": "2026-06-10T12:00:00Z",
  "schema": "weather.observation.v1",
  "payload": {
    "stationId": "KSTL",
    "timestamp": "2026-06-10T12:00:00Z",
    "conditionCode": 0,
    "temperatureC": 22.5
  }
}