Rewrite public API documentation
This commit is contained in:
736
docs/api.md
736
docs/api.md
@@ -1,441 +1,355 @@
|
|||||||
# weatherapi External API
|
# weatherapi HTTP API
|
||||||
|
|
||||||
This document describes the public HTTP API exposed by `weatherapi` for external consumers.
|
This is the canonical public HTTP contract for `weatherapi`. The service is a
|
||||||
|
read-only API over the latest weather records available in the configured
|
||||||
|
weatherfeeder-populated Postgres database.
|
||||||
|
|
||||||
## Base URL
|
## Base URL
|
||||||
|
|
||||||
The service is typically served at your deployment host, for example:
|
All paths are relative to the deployment root:
|
||||||
|
|
||||||
- `https://weather.example.com`
|
|
||||||
|
|
||||||
All paths below are relative to the service root.
|
|
||||||
|
|
||||||
## Common Conventions
|
|
||||||
|
|
||||||
### Response envelope
|
|
||||||
|
|
||||||
All endpoints return a top-level envelope:
|
|
||||||
|
|
||||||
- `data`: endpoint payload or `null` when no current/latest resource is available.
|
|
||||||
|
|
||||||
JSON example:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {"...": "..."}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output format
|
|
||||||
|
|
||||||
Supported via `format` query parameter (case-insensitive):
|
|
||||||
|
|
||||||
- `json` (default)
|
|
||||||
- `xml`
|
|
||||||
- `text`
|
|
||||||
|
|
||||||
### Units
|
|
||||||
|
|
||||||
Supported via `units` query parameter (case-insensitive):
|
|
||||||
|
|
||||||
- `metric` (default)
|
|
||||||
- `us`
|
|
||||||
|
|
||||||
Endpoints that include unit-based numeric fields return either metric or US field variants depending on this value.
|
|
||||||
|
|
||||||
### Precision
|
|
||||||
|
|
||||||
Supported where documented via `precision` query parameter:
|
|
||||||
|
|
||||||
- integer range: `0` to `2`
|
|
||||||
- controls decimal rounding of numeric output fields
|
|
||||||
|
|
||||||
### Timezone (`tz` / `TZ`)
|
|
||||||
|
|
||||||
Supported where documented:
|
|
||||||
|
|
||||||
- accepted values include:
|
|
||||||
- IANA timezone names (example: `America/Chicago`)
|
|
||||||
- common US abbreviations (example: `CDT`, `EST`)
|
|
||||||
- UTC offsets in `±H`, `±HH`, or `±HH:MM` (example: `-5`, `+09:30`)
|
|
||||||
- aliases including `Chicago` and `Stl`
|
|
||||||
- `tz` and `TZ` are treated equivalently
|
|
||||||
- if both are provided, they must match exactly or the request fails
|
|
||||||
|
|
||||||
Timezone affects datetime rendering and day-slice filtering for `/today` and `/tomorrow` forecast routes.
|
|
||||||
It also affects weather story and discussion datetime rendering.
|
|
||||||
|
|
||||||
### Query validation
|
|
||||||
|
|
||||||
- Unknown query parameters are rejected with `400 Bad Request`.
|
|
||||||
- Invalid parameter values are rejected with `400 Bad Request`.
|
|
||||||
|
|
||||||
Error response body follows the service error envelope; exact fields may vary by error type.
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
## `GET /observations`
|
|
||||||
|
|
||||||
Returns the latest weather observation.
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us`
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
- `precision`: `0..2`
|
|
||||||
|
|
||||||
Response `data` fields:
|
|
||||||
|
|
||||||
- `stationId` (string, optional)
|
|
||||||
- `stationName` (string, optional)
|
|
||||||
- `timestamp` (RFC3339 datetime, required)
|
|
||||||
- `conditionCode` (integer WMO code, required)
|
|
||||||
- `isDay` (boolean, optional)
|
|
||||||
- `textDescription` (string, optional)
|
|
||||||
- Metric mode fields:
|
|
||||||
- `temperatureC`, `dewpointC`, `windSpeedKmh`, `windGustKmh`, `barometricPressurePa`, `visibilityMeters`, `relativeHumidityPercent`, `apparentTemperatureC` (number, optional)
|
|
||||||
- `windDirectionDegrees` (number, optional)
|
|
||||||
- US mode fields:
|
|
||||||
- `temperatureF`, `dewpointF`, `windSpeedMph`, `windGustMph`, `barometricPressureInHg`, `visibilityMiles`, `relativeHumidityPercent`, `apparentTemperatureF` (number, optional)
|
|
||||||
- `windDirectionDegrees` (number, optional)
|
|
||||||
- `presentWeather` (array, optional)
|
|
||||||
|
|
||||||
## `GET /alerts/active`
|
|
||||||
|
|
||||||
Returns the latest active alert run.
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us` (accepted; does not materially alter alert payload)
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
|
|
||||||
Response `data` fields:
|
|
||||||
|
|
||||||
- Weather alert run object from canonical model (includes run metadata and active alerts list).
|
|
||||||
|
|
||||||
## `GET /conditions/current`
|
|
||||||
|
|
||||||
Returns current conditions synthesized from latest observation/forecast data.
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us`
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
- `precision`: `0..2`
|
|
||||||
|
|
||||||
Response `data` fields:
|
|
||||||
|
|
||||||
- Common:
|
|
||||||
- `conditionText` (string, optional)
|
|
||||||
- `isDay` (boolean, optional)
|
|
||||||
- `relativeHumidityPercent` (number, optional)
|
|
||||||
- `windDirectionDegrees` (number, optional)
|
|
||||||
- Metric mode:
|
|
||||||
- `temperatureC`, `apparentTemperatureC`, `dewpointC`, `windSpeedKmh` (number, optional)
|
|
||||||
- US mode:
|
|
||||||
- `temperatureF`, `apparentTemperatureF`, `dewpointF`, `windSpeedMph` (number, optional)
|
|
||||||
|
|
||||||
## Forecast endpoints
|
|
||||||
|
|
||||||
- `GET /forecast/hourly`
|
|
||||||
- `GET /forecast/hourly/today`
|
|
||||||
- `GET /forecast/hourly/tomorrow`
|
|
||||||
- `GET /forecast/narrative`
|
|
||||||
- `GET /forecast/narrative/today`
|
|
||||||
- `GET /forecast/narrative/tomorrow`
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us`
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
- `precision`: `0..2`
|
|
||||||
- `tz` or `TZ`: timezone selector
|
|
||||||
|
|
||||||
Day-slice routes:
|
|
||||||
|
|
||||||
- `/today` returns periods with `period.startTime` in the current calendar day for the resolved timezone.
|
|
||||||
- `/tomorrow` returns periods with `period.startTime` in the next calendar day for the resolved timezone.
|
|
||||||
|
|
||||||
Response `data` fields:
|
|
||||||
|
|
||||||
- Run-level:
|
|
||||||
- `locationId` (string, optional)
|
|
||||||
- `locationName` (string, optional)
|
|
||||||
- `issuedAt` (RFC3339 datetime, required)
|
|
||||||
- `updatedAt` (RFC3339 datetime, optional)
|
|
||||||
- `product` (string, required; e.g. `hourly`, `narrative`)
|
|
||||||
- `latitude`, `longitude` (number, optional)
|
|
||||||
- Metric mode: `elevationMeters` (number, optional)
|
|
||||||
- US mode: `elevationFeet` (number, optional)
|
|
||||||
- `periods` (array, required)
|
|
||||||
- Period fields:
|
|
||||||
- `startTime`, `endTime` (RFC3339 datetime, required)
|
|
||||||
- `name` (string, optional)
|
|
||||||
- `isDay` (boolean, optional)
|
|
||||||
- `conditionCode` (integer WMO code, optional)
|
|
||||||
- `textDescription` (string, optional)
|
|
||||||
- Metric mode (optional):
|
|
||||||
- `temperatureC`, `temperatureCMin`, `temperatureCMax`, `dewpointC`, `windSpeedKmh`, `windGustKmh`, `barometricPressurePa`, `visibilityMeters`, `apparentTemperatureC`, `cloudCoverPercent`, `probabilityOfPrecipitationPercent`, `precipitationAmountMm`, `snowfallDepthMM`, `uvIndex`, `relativeHumidityPercent`, `windDirectionDegrees`
|
|
||||||
- US mode (optional):
|
|
||||||
- `temperatureF`, `temperatureFMin`, `temperatureFMax`, `dewpointF`, `windSpeedMph`, `windGustMph`, `barometricPressureInHg`, `visibilityMiles`, `apparentTemperatureF`, `cloudCoverPercent`, `probabilityOfPrecipitationPercent`, `precipitationAmountIn`, `snowfallDepthIn`, `uvIndex`, `relativeHumidityPercent`, `windDirectionDegrees`
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
- Narrative periods may omit `conditionCode`.
|
|
||||||
- Text format uses forecast-specific templates (`hourly` and `narrative`).
|
|
||||||
|
|
||||||
## Discussion endpoints
|
|
||||||
|
|
||||||
- `GET /discussion`
|
|
||||||
- `GET /discussion/key-messages`
|
|
||||||
- `GET /discussion/short-term`
|
|
||||||
- `GET /discussion/long-term`
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us` (accepted; does not materially alter discussion payload)
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
- `tz` or `TZ`: timezone selector
|
|
||||||
|
|
||||||
Response `data` fields:
|
|
||||||
|
|
||||||
- `/discussion`:
|
|
||||||
- `officeId` (string, optional)
|
|
||||||
- `officeName` (string, optional)
|
|
||||||
- `product` (string, required)
|
|
||||||
- `issuedAt` (RFC3339 datetime, required)
|
|
||||||
- `updatedAt` (RFC3339 datetime, optional)
|
|
||||||
- `keyMessages` (array of string)
|
|
||||||
- `shortTerm` (object, optional)
|
|
||||||
- `longTerm` (object, optional)
|
|
||||||
- `/discussion/key-messages`:
|
|
||||||
- `officeId`, `officeName`, `product`, `issuedAt`, `updatedAt`
|
|
||||||
- `keyMessages` (array of string)
|
|
||||||
- `/discussion/short-term`:
|
|
||||||
- `officeId`, `officeName`, `product`, `issuedAt`, `updatedAt`
|
|
||||||
- `shortTerm` (object, optional)
|
|
||||||
- `/discussion/long-term`:
|
|
||||||
- `officeId`, `officeName`, `product`, `issuedAt`, `updatedAt`
|
|
||||||
- `longTerm` (object, optional)
|
|
||||||
|
|
||||||
Discussion section object fields:
|
|
||||||
|
|
||||||
- `title` (string, optional)
|
|
||||||
- `narrative` (string, optional)
|
|
||||||
- `issuedAt` (RFC3339 datetime, optional)
|
|
||||||
|
|
||||||
## Weather Stories endpoints
|
|
||||||
|
|
||||||
- `GET /weatherstories`
|
|
||||||
- `GET /weatherstories/latest`
|
|
||||||
|
|
||||||
Query parameters:
|
|
||||||
|
|
||||||
- `units`: `metric` | `us` (accepted; does not materially alter weather story payloads)
|
|
||||||
- `format`: `json` | `xml` | `text`
|
|
||||||
- `tz` or `TZ`: timezone selector
|
|
||||||
|
|
||||||
Response behavior:
|
|
||||||
|
|
||||||
- `/weatherstories` returns the latest stored weather story run and its ordered stories.
|
|
||||||
- `/weatherstories/latest` returns the single story with the greatest `updatedAt`.
|
|
||||||
- When no weather story data exists, `data` is `null`.
|
|
||||||
|
|
||||||
`/weatherstories` response `data` fields:
|
|
||||||
|
|
||||||
- `officeId` (string, optional)
|
|
||||||
- `asOf` (RFC3339 datetime, required)
|
|
||||||
- `stories` (array, required)
|
|
||||||
|
|
||||||
Weather story fields:
|
|
||||||
|
|
||||||
- `officeId` (string, optional)
|
|
||||||
- `startTime` (RFC3339 datetime, required)
|
|
||||||
- `endTime` (RFC3339 datetime, required)
|
|
||||||
- `updatedAt` (RFC3339 datetime, required)
|
|
||||||
- `title` (string, optional)
|
|
||||||
- `description` (string, optional)
|
|
||||||
- `altText` (string, optional)
|
|
||||||
- `priority` (boolean, required)
|
|
||||||
- `order` (integer, required)
|
|
||||||
- `downloadUrl` (string, optional)
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Observation (JSON, metric)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /observations?format=json&units=metric&precision=1
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"stationId": "KSTL",
|
|
||||||
"timestamp": "2026-05-29T14:00:00Z",
|
|
||||||
"conditionCode": 3,
|
|
||||||
"isDay": true,
|
|
||||||
"textDescription": "Partly cloudy",
|
|
||||||
"temperatureC": 24.4,
|
|
||||||
"windSpeedKmh": 17.2,
|
|
||||||
"relativeHumidityPercent": 56.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Alerts (JSON)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /alerts/active?format=json
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"asOf": "2026-05-29T14:00:00Z",
|
|
||||||
"alerts": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Current conditions (JSON, US)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /conditions/current?format=json&units=us&precision=1
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"conditionText": "Partly cloudy",
|
|
||||||
"isDay": true,
|
|
||||||
"temperatureF": 75.9,
|
|
||||||
"apparentTemperatureF": 76.1,
|
|
||||||
"windSpeedMph": 10.7,
|
|
||||||
"relativeHumidityPercent": 56.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Forecast narrative (JSON, optional `conditionCode`)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /forecast/narrative?format=json&units=metric&precision=1&tz=America/Chicago
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"locationId": "nws-lsx-grid-90-74",
|
|
||||||
"issuedAt": "2026-05-29T10:30:00-05:00",
|
|
||||||
"product": "narrative",
|
|
||||||
"periods": [
|
|
||||||
{
|
|
||||||
"startTime": "2026-05-29T13:00:00-05:00",
|
|
||||||
"endTime": "2026-05-29T19:00:00-05:00",
|
|
||||||
"name": "Today",
|
|
||||||
"isDay": true,
|
|
||||||
"textDescription": "Partly sunny, with a high near 81.",
|
|
||||||
"temperatureC": 27.2,
|
|
||||||
"windSpeedKmh": 18.0,
|
|
||||||
"probabilityOfPrecipitationPercent": 10.0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Forecast hourly today (text)
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /forecast/hourly/today?format=text&units=us&precision=1&tz=CDT
|
|
||||||
```
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
<plain text forecast output>
|
http://localhost:8080
|
||||||
```
|
```
|
||||||
|
|
||||||
### Discussion key messages (JSON)
|
Use your deployment host in production.
|
||||||
|
|
||||||
```http
|
## Authentication
|
||||||
GET /discussion/key-messages?format=json&tz=Chicago
|
|
||||||
```
|
`weatherapi` does not implement authentication or authorization. Put access
|
||||||
|
control in front of the service when a deployment requires it.
|
||||||
|
|
||||||
|
## Response Envelope
|
||||||
|
|
||||||
|
Successful JSON and XML responses use a top-level envelope:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {}
|
||||||
"officeId": "LSX",
|
|
||||||
"product": "discussion",
|
|
||||||
"issuedAt": "2026-05-29T09:25:00-05:00",
|
|
||||||
"keyMessages": [
|
|
||||||
"Scattered showers possible this evening.",
|
|
||||||
"Warmer temperatures this weekend."
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Weather stories (JSON)
|
When no latest/current resource exists, the request still succeeds and returns
|
||||||
|
`data: null`.
|
||||||
|
|
||||||
```http
|
Text responses are rendered from endpoint-specific templates. When the payload
|
||||||
GET /weatherstories?format=json&tz=America/Chicago
|
is missing, the templates return a short no-data message.
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
## Formats
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"officeId": "LSX",
|
|
||||||
"asOf": "2026-05-30T04:00:34-05:00",
|
|
||||||
"stories": [
|
|
||||||
{
|
|
||||||
"officeId": "LSX",
|
|
||||||
"startTime": "2026-05-30T03:46:00-05:00",
|
|
||||||
"endTime": "2026-05-31T06:00:00-05:00",
|
|
||||||
"updatedAt": "2026-05-30T04:00:34-05:00",
|
|
||||||
"title": "Several Chances for Rain Through Monday",
|
|
||||||
"description": "Scattered showers and thunderstorms remain possible.",
|
|
||||||
"altText": "This slide shows the forecast for today through Tuesday.",
|
|
||||||
"priority": false,
|
|
||||||
"order": 1,
|
|
||||||
"downloadUrl": "https://api.weather.gov/offices/LSX/weatherstories/download/3228e499-2aae-45a8-9ff9-1c060311026f"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Latest weather story (JSON)
|
Every implemented endpoint can produce:
|
||||||
|
|
||||||
```http
|
| Format | Media type |
|
||||||
GET /weatherstories/latest?format=json&tz=CDT
|
| --- | --- |
|
||||||
```
|
| `json` | `application/json` |
|
||||||
|
| `xml` | `application/xml` |
|
||||||
|
| `text` | `text/plain` |
|
||||||
|
|
||||||
```json
|
Format selection is:
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"officeId": "LSX",
|
|
||||||
"startTime": "2026-05-30T03:46:00-05:00",
|
|
||||||
"endTime": "2026-05-31T06:00:00-05:00",
|
|
||||||
"updatedAt": "2026-05-30T04:00:34-05:00",
|
|
||||||
"title": "Several Chances for Rain Through Monday",
|
|
||||||
"description": "Scattered showers and thunderstorms remain possible.",
|
|
||||||
"priority": false,
|
|
||||||
"order": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Invalid timezone error example
|
1. `format` query parameter;
|
||||||
|
2. `Accept` header;
|
||||||
|
3. configured `server.default_format`.
|
||||||
|
|
||||||
```http
|
`format` values are case-insensitive. Unsupported formats return `406
|
||||||
GET /forecast/narrative?tz=not-a-timezone
|
Not Acceptable` with an error envelope.
|
||||||
```
|
|
||||||
|
## Shared Query Rules
|
||||||
|
|
||||||
|
Unknown query parameters are rejected with `400 Bad Request`.
|
||||||
|
|
||||||
|
| Parameter | Values | Default | Supported on |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `format` | `json`, `xml`, `text` | configured default | all endpoints |
|
||||||
|
| `units` | `metric`, `us` | `metric` | all endpoints |
|
||||||
|
| `precision` | integer `0` through `2` | `0` | observations, current conditions, forecasts |
|
||||||
|
| `tz` or `TZ` | timezone selector | UTC/no conversion | forecasts, discussions, weather stories |
|
||||||
|
|
||||||
|
`units`, `format`, and `precision` values are normalized case-insensitively
|
||||||
|
where applicable. `units=metric` returns metric field names; `units=us` returns
|
||||||
|
US-customary field names for unit-bearing payloads. Alerts, discussions, and
|
||||||
|
weather stories accept `units` but their current payload fields are not
|
||||||
|
materially changed by it.
|
||||||
|
|
||||||
|
`precision` controls numeric rounding. The default `0` rounds to whole numbers.
|
||||||
|
`precision` is rejected on alerts, discussions, and weather stories.
|
||||||
|
|
||||||
|
Timezone selectors accepted by `tz` / `TZ`:
|
||||||
|
|
||||||
|
- IANA timezone names such as `America/Chicago`;
|
||||||
|
- common US abbreviations such as `CDT`, `CST`, `EDT`, `EST`, `MDT`, `MST`,
|
||||||
|
`PDT`, and `PST`;
|
||||||
|
- UTC offsets in `+H`, `+HH`, `+HH:MM`, `-H`, `-HH`, or `-HH:MM` form, bounded
|
||||||
|
to `-14:00` through `+14:00`;
|
||||||
|
- aliases `Chicago` and `Stl`, both mapped to `America/Chicago`.
|
||||||
|
|
||||||
|
If both `tz` and `TZ` are provided, their values must match
|
||||||
|
case-insensitively. Timezone conversion affects rendered timestamps and forecast
|
||||||
|
`/today` and `/tomorrow` day-slice filtering. Without a timezone parameter,
|
||||||
|
day-slice routes use UTC.
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
API errors use a stable error envelope:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"error": {
|
"error": {
|
||||||
"code": "invalid_parameter",
|
"code": "invalid_parameter",
|
||||||
"message": "tz must be a valid timezone"
|
"message": "..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Implemented API error statuses:
|
||||||
|
|
||||||
|
| Status | Code | Cause |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `400 Bad Request` | `invalid_parameter` | unknown query parameter, invalid parameter value, invalid timezone, conflicting `tz` / `TZ`, or unsupported parameter on a route |
|
||||||
|
| `406 Not Acceptable` | `unsupported_format` | requested response format is not supported by the endpoint/renderers |
|
||||||
|
|
||||||
|
Unhandled service or database errors are returned as server errors by the
|
||||||
|
runtime.
|
||||||
|
|
||||||
|
## Behavior Not Implemented
|
||||||
|
|
||||||
|
`weatherapi` does not implement pagination, cache-control headers, rate-limit
|
||||||
|
headers, idempotency keys, retries, writes, or historical browsing outside the
|
||||||
|
implemented latest-resource and forecast day-slice routes.
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### Observations
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /observations
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the latest weather observation.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`, `precision`.
|
||||||
|
|
||||||
|
Metric `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `stationId`, `stationName` | string | optional |
|
||||||
|
| `timestamp` | RFC3339 datetime | required when `data` is not null |
|
||||||
|
| `conditionCode` | integer | WMO weather code |
|
||||||
|
| `isDay` | boolean | optional |
|
||||||
|
| `textDescription` | string | optional |
|
||||||
|
| `temperatureC`, `dewpointC`, `apparentTemperatureC` | number | optional |
|
||||||
|
| `windDirectionDegrees`, `windSpeedKmh`, `windGustKmh` | number | optional |
|
||||||
|
| `barometricPressurePa`, `visibilityMeters` | number | optional |
|
||||||
|
| `relativeHumidityPercent` | number | optional |
|
||||||
|
| `presentWeather` | array | optional |
|
||||||
|
|
||||||
|
US mode replaces unit-bearing fields with `temperatureF`, `dewpointF`,
|
||||||
|
`apparentTemperatureF`, `windSpeedMph`, `windGustMph`,
|
||||||
|
`barometricPressureInHg`, and `visibilityMiles`. Direction and percentage
|
||||||
|
fields keep the same names.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /observations?units=us&precision=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Current Conditions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /conditions/current
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns current conditions aggregated from recent `observations` rows. The
|
||||||
|
implemented observation window is 30 minutes.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`, `precision`.
|
||||||
|
|
||||||
|
Common `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `conditionText` | string | optional text derived from WMO code and day/night flag |
|
||||||
|
| `isDay` | boolean | optional |
|
||||||
|
| `relativeHumidityPercent` | number | optional |
|
||||||
|
| `windDirectionDegrees` | number | optional |
|
||||||
|
|
||||||
|
Metric fields: `temperatureC`, `apparentTemperatureC`, `dewpointC`,
|
||||||
|
`windSpeedKmh`.
|
||||||
|
|
||||||
|
US fields: `temperatureF`, `apparentTemperatureF`, `dewpointF`,
|
||||||
|
`windSpeedMph`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /conditions/current?format=json&precision=0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Active Alerts
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /alerts/active
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the latest active-alert snapshot.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`.
|
||||||
|
|
||||||
|
Run `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `locationId`, `locationName` | string | optional |
|
||||||
|
| `asOf` | RFC3339 datetime | required when `data` is not null |
|
||||||
|
| `latitude`, `longitude` | number | optional |
|
||||||
|
| `alerts` | array | active alerts, possibly empty |
|
||||||
|
|
||||||
|
Alert fields include `id`, `event`, `headline`, `severity`, `urgency`,
|
||||||
|
`certainty`, `status`, `messageType`, `category`, `response`, `description`,
|
||||||
|
`instruction`, `sent`, `effective`, `onset`, `expires`, `areaDescription`,
|
||||||
|
`senderName`, and `references`. Most alert fields are optional except `id` when
|
||||||
|
an alert item is present.
|
||||||
|
|
||||||
|
Reference fields are `id`, `identifier`, `sender`, and `sent`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /alerts/active?format=text
|
||||||
|
```
|
||||||
|
|
||||||
|
### Forecasts
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /forecast/hourly
|
||||||
|
GET /forecast/hourly/today
|
||||||
|
GET /forecast/hourly/tomorrow
|
||||||
|
GET /forecast/narrative
|
||||||
|
GET /forecast/narrative/today
|
||||||
|
GET /forecast/narrative/tomorrow
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the latest hourly or narrative forecast run. `/today` and `/tomorrow`
|
||||||
|
return a copy of the latest run with `periods` filtered by each period's
|
||||||
|
`startTime` in the resolved timezone. If no periods match, `data` remains an
|
||||||
|
object and `periods` is an empty array.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`, `precision`, `tz` / `TZ`.
|
||||||
|
|
||||||
|
Run `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `locationId`, `locationName` | string | optional |
|
||||||
|
| `issuedAt` | RFC3339 datetime | required when `data` is not null |
|
||||||
|
| `updatedAt` | RFC3339 datetime | optional |
|
||||||
|
| `product` | string | `hourly` or `narrative` for implemented routes |
|
||||||
|
| `latitude`, `longitude` | number | optional |
|
||||||
|
| `elevationMeters` or `elevationFeet` | number | optional, depends on `units` |
|
||||||
|
| `periods` | array | ordered forecast periods |
|
||||||
|
|
||||||
|
Metric period fields:
|
||||||
|
|
||||||
|
`startTime`, `endTime`, `name`, `isDay`, `conditionCode`,
|
||||||
|
`textDescription`, `temperatureC`, `temperatureCMin`, `temperatureCMax`,
|
||||||
|
`dewpointC`, `relativeHumidityPercent`, `windDirectionDegrees`,
|
||||||
|
`windSpeedKmh`, `windGustKmh`, `barometricPressurePa`, `visibilityMeters`,
|
||||||
|
`apparentTemperatureC`, `cloudCoverPercent`,
|
||||||
|
`probabilityOfPrecipitationPercent`, `precipitationAmountMm`,
|
||||||
|
`snowfallDepthMm`, and `uvIndex`.
|
||||||
|
|
||||||
|
US mode uses the same non-unit fields and replaces unit-bearing fields with
|
||||||
|
`temperatureF`, `temperatureFMin`, `temperatureFMax`, `dewpointF`,
|
||||||
|
`windSpeedMph`, `windGustMph`, `barometricPressureInHg`, `visibilityMiles`,
|
||||||
|
`apparentTemperatureF`, `precipitationAmountIn`, `snowfallDepthIn`, and
|
||||||
|
`elevationFeet` at run level.
|
||||||
|
|
||||||
|
`startTime` and `endTime` are required for each period. Other period fields are
|
||||||
|
optional, including `conditionCode`; narrative forecasts may omit it.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /forecast/hourly?units=us&precision=1&TZ=-5
|
||||||
|
GET /forecast/narrative/tomorrow?format=text&tz=Chicago
|
||||||
|
```
|
||||||
|
|
||||||
|
### Forecast Discussions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /discussion
|
||||||
|
GET /discussion/key-messages
|
||||||
|
GET /discussion/short-term
|
||||||
|
GET /discussion/long-term
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the latest forecast discussion or a focused subresource.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`, `tz` / `TZ`.
|
||||||
|
|
||||||
|
Full discussion `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `officeId`, `officeName` | string | optional |
|
||||||
|
| `product` | string | currently `afd` from weatherfeeder data |
|
||||||
|
| `issuedAt` | RFC3339 datetime | required when `data` is not null |
|
||||||
|
| `updatedAt` | RFC3339 datetime | optional |
|
||||||
|
| `keyMessages` | array of strings | optional |
|
||||||
|
| `shortTerm`, `longTerm` | object | optional section objects |
|
||||||
|
|
||||||
|
Discussion section fields are `qualifier`, `issuedAt`, and `text`, all
|
||||||
|
optional.
|
||||||
|
|
||||||
|
Subresources return the same metadata plus only their focused field:
|
||||||
|
`keyMessages`, `shortTerm`, or `longTerm`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /discussion/short-term?format=text&tz=CDT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weather Stories
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /weatherstories
|
||||||
|
GET /weatherstories/latest
|
||||||
|
```
|
||||||
|
|
||||||
|
`/weatherstories` returns the latest weather-story run and its ordered stories.
|
||||||
|
`/weatherstories/latest` returns the latest individual story.
|
||||||
|
|
||||||
|
Query parameters: `format`, `units`, `tz` / `TZ`.
|
||||||
|
|
||||||
|
Run `data` fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `officeId` | string | optional |
|
||||||
|
| `asOf` | RFC3339 datetime | required when `data` is not null |
|
||||||
|
| `stories` | array | ordered story objects |
|
||||||
|
|
||||||
|
Story fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `officeId` | string | optional |
|
||||||
|
| `startTime`, `endTime`, `updatedAt` | RFC3339 datetime | required when a story is present |
|
||||||
|
| `title`, `description`, `altText`, `downloadUrl` | string | optional |
|
||||||
|
| `priority` | boolean | required when a story is present |
|
||||||
|
| `order` | integer | required when a story is present |
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /weatherstories?tz=America/Chicago
|
||||||
|
GET /weatherstories/latest?format=xml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Copyable Requests
|
||||||
|
|
||||||
|
See [`examples/requests.http`](../examples/requests.http) for a compact set of
|
||||||
|
requests covering the implemented endpoint families.
|
||||||
|
|||||||
45
examples/requests.http
Normal file
45
examples/requests.http
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
@baseUrl = http://localhost:8080
|
||||||
|
|
||||||
|
### Latest observation
|
||||||
|
GET {{baseUrl}}/observations?units=metric&precision=1
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Current conditions
|
||||||
|
GET {{baseUrl}}/conditions/current?units=us&precision=0
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Active alerts as text
|
||||||
|
GET {{baseUrl}}/alerts/active?format=text
|
||||||
|
|
||||||
|
### Hourly forecast in US units
|
||||||
|
GET {{baseUrl}}/forecast/hourly?units=us&precision=1&tz=Chicago
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Hourly forecast for today
|
||||||
|
GET {{baseUrl}}/forecast/hourly/today?tz=CDT
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Narrative forecast for tomorrow as text
|
||||||
|
GET {{baseUrl}}/forecast/narrative/tomorrow?format=text&tz=America/Chicago
|
||||||
|
|
||||||
|
### Full forecast discussion
|
||||||
|
GET {{baseUrl}}/discussion?tz=CDT
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Forecast discussion key messages as text
|
||||||
|
GET {{baseUrl}}/discussion/key-messages?format=text
|
||||||
|
|
||||||
|
### Forecast discussion short term
|
||||||
|
GET {{baseUrl}}/discussion/short-term?tz=CDT
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Forecast discussion long term
|
||||||
|
GET {{baseUrl}}/discussion/long-term?TZ=-5
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Weather stories
|
||||||
|
GET {{baseUrl}}/weatherstories?tz=America/Chicago
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Latest weather story as XML
|
||||||
|
GET {{baseUrl}}/weatherstories/latest?format=xml
|
||||||
Reference in New Issue
Block a user