4.5 KiB
Weather API Integration
This document describes the external Weather API contract used by
weatherreporter.
Purpose
weatherreporter uses a configured Weather API base URL to fetch normalized
weather source data and assemble a forecast.Bundle. This is an integration
contract for the project adapter, not a complete public API reference for the
upstream service.
Base URL
weather_api.base_url must be an absolute URL. Adapter requests join this base
URL with the endpoint paths listed below. Generation and explicit bundle fetches
fail before any HTTP request when the base URL is empty or not absolute.
The HTTP client uses weather_api.timeout.
Response Envelope
Every response used by the adapter must be JSON with a top-level data field:
{
"data": {}
}
For most sources, data: null is treated as a missing source. Missing optional
sources follow the configured missing-source policy. Missing hourly forecast
data fails bundle fetching because hourly periods are required for report
generation.
/alerts/active is the exception: a successful response with data: null
means the endpoint was checked and there are no current active alerts. The
adapter records a non-missing alerts source and an empty alert run.
Malformed JSON envelopes, non-2xx statuses, and response read failures include endpoint context in returned errors. Decode errors include source context when they fail the fetch; optional malformed sources follow the missing-source policy.
Query Parameters
The adapter sends these query parameters:
format: fromweather_api.format; the implemented configuration requiresjsonunits: fromweather_api.unitsprecision: fromweather_api.precisionon observations, current conditions, hourly forecast, and narrative forecast requeststz: fromweather_api.timezoneon hourly forecast, narrative forecast, and discussion requests
Alerts do not receive precision or tz. Weather story requests receive only
format=json.
Endpoints Used
The adapter fetches these endpoints once per bundle:
/observations/conditions/current/forecast/hourly/forecast/narrative/alerts/active/discussion/weatherstories/latest
weatherreporter does not call day-slice forecast endpoints or discussion
subsection endpoints. Report-period selection and daypart summarization happen
inside Go after the full hourly and narrative products are fetched.
Required And Optional Sources
Hourly forecast is required:
data: nullfor/forecast/hourlyfails the fetch.- an hourly forecast with no
periodsfails the fetch. - malformed hourly data fails the fetch.
Other fetched sources are optional and follow missing_source.default or a
source-specific missing_source.sources policy:
observationsfor/observationscurrentfor/conditions/currentnarrativefor/forecast/narrativealertsfor/alerts/activediscussionfor/discussionweather_storyfor/weatherstories/latest
The adapter also creates a missing stub source record for daily because that
source slot exists in the internal bundle but is not fetched from the Weather
API.
Policy behavior:
error: fail the fetch for that sourcewarn: omit the source data, add a warning, and continuenone: omit the source data and continue without a warning
For /alerts/active, an HTTP error or missing data field still fails or
follows the relevant error path, but explicit data: null is not a
missing-source condition.
Source Identity
For source payloads accepted into the bundle, including the explicit null
alerts payload, the adapter records:
- source name
- endpoint path
- query parameters sent
- fetch time
- source issue and update timestamps when present in the payload
- SHA-256 hash of the compact raw
dataJSON
Warnings are recorded both on the affected source and on the bundle-level warnings list.
Compatibility Assumptions
The adapter expects payload fields compatible with the internal forecast bundle
types in internal/forecast/bundle.go, including:
- observation timestamps and observation values
- current condition values
- forecast run metadata and
periods - active alert run data
- discussion metadata, key messages, and short/long-term section text
- latest weather story title, description, timing, priority, order, alt text, and download URL
The adapter intentionally keeps upstream transport and envelope details inside
internal/adapters/weatherapi; downstream packages consume the normalized
bundle.