Back to radar# v0.7 optional-layer APIs
All endpoints use existing Basic Auth / X-API-Key settings.
- GET `/api/observations?bbox=west,south,east,north`: current METAR reports with station coordinates, UTC observation time, values, stale/error flags. Up to 500 reports; regional queries recommended. No historical surface-observation API in this release.
- GET `/api/lightning?bbox=west,south,east,north&time=ISO_TIME&minutes=5`: quality-screened NOAA GOES optical flash centroids for 1/2/5/10 minutes ending at the given radar timestamp. HTTP 202/state=loading means poll again, normally after a few seconds. Ready results expose availability/partial flags, file count, actual flash times and source satellite. Up to 5000 flashes. At most 3 pending jobs, one background worker; cache/results are bounded. These are total-lightning optical centroids, not ground-strike points.
- GET `/api/contours/SITE/PRODUCT/TILT/SCAN`: approximate GeoJSON contours for an already prepared mesh/mesh30/posh/azshear/rotation60 grid. Use `/api/frames` first, then its scan ID. 429 means the contour worker is busy; retry later.
- New `/api/frames` product values: mesh, mesh30, posh, azshear, rotation60. Same binary frame contract; metadata specifies units and transparent background thresholds. Native negative shear is retained. MRMS severe loops cap at 48 scans and may thin further under cache pressure.
- `/api/config` exposes `features` booleans. Disabled features return 503; the PWA suppresses their controls. `/api/server` includes new cache/source status.
# Nightwatch image API ยท v0.6.0
The API runs on the same host/port as the PWA. It renders real radar scans to PNG using bundled geography. No GPU or browser session is required. All times must include a UTC offset; `Z` means UTC.
## Access
Existing Basic Auth protects the shell and APIs when `RADAR_USERNAME` and `RADAR_PASSWORD` are configured. Set both for internet exposure, use the provided HTTPS proxy, and optionally set `RADAR_API_KEY` for other applications. Send the key in `X-API-Key`; it bypasses Basic Auth for `/api/` only. A key does not enable authentication by itself when Basic Auth is disabled. Do not put credentials in URLs. LAN/VPN deployments can keep the current authentication configuration.
## One image
```bash
curl -H 'X-API-Key:YOUR_KEY' \
'https://RADAR_HOST/api/image?site=KCLX&product=reflectivity&bbox=-84,30,-78,35&time=2026-10-26T18:00:00Z&width=960&height=640'
```
Omit `time` to request current radar. The first request normally returns HTTP **202** with a JSON job ID, `Location` and `Retry-After`. Poll the job endpoint until `state=ready`, then download the returned relative URL. Repeating the identical GET returns the PNG once ready. Do not save an HTTP 202 response as a PNG. Latest requests share the same result within a UTC minute.
Time selection uses the newest real scan **at or before** the requested time, within 15 minutes by default. No interpolation or invented scans. The job response lists actual selected scan times. The satellite API separately uses nearest-time matching, which can be earlier or later.
## Queue an export
`POST /api/images/jobs`, JSON:
```json
{
"site": "KCLX",
"product": "reflectivity",
"tilt": 0.5,
"bbox": [-84, 30, -78, 35],
"width": 960,
"height": 640,
"start": "2026-10-26T16:00:00Z",
"end": "2026-10-26T18:00:00Z",
"interval": 5,
"format": "zip",
"roads": true,
"boundaries": true,
"timestamp": true,
"legend": true,
"weak": false,
"opacity": 0.9
}
```
- `bbox`: west, south, east, north. Web Mercator rendering; latitude -85 to 85; dateline-crossing extents are not supported.
- `product`: reflectivity, velocity, cc, zdr, storm_velocity, rain_hour, rain_total, mrms.
- `tilt`: 0.5, 1.5, 2.5, 3.5 degrees. Products without elevation ignore this for source selection.
- `width`, `height`: 128โ1440 pixels each.
- `start` + `end`: up to 7 days; ZIP/GIF only. Omit `start` for one image. Omit both for latest.
- `interval`: 0, 1, 2, 5, 10, 15, 30 or 60 minutes. Bins select real scans; they do not guarantee exact clock spacing.
- `format`: png, gif or zip. GIF playback is 450 ms per frame. ZIP includes PNGs and a timestamp manifest.
- `tolerance`: 1โ60 minutes, default 15, for single-image lookback only.
- Up to **48 rendered images** per job, evenly sampled across the selected interval. Radar preparation can involve up to 240 underlying frames.
- PNG/GIF server exports contain radar, timestamp, legend and requested roads/boundaries. Satellite, warnings, storm signatures and pins are supported by **browser clean exports**, not the server image API in this release.
- A single-site radar has finite range; MRMS uses the existing regional CONUS crop around the selected site. A large bbox does not create extra coverage.
`GET /api/images/jobs/ID` returns queued/working/ready/error/cancelled, status text, actual scans and download URL. `DELETE` cancels queued work and prevents publication of a running result; an already executing decode/render may finish. Downloads: `GET /api/images/jobs/ID/download`.
There are at most 8 queued/working exports. Overload returns 429. Jobs expire on restart; request again. Completed artifacts use an independent `IMAGE_CACHE_MB` budget and expire after 24 hours since last use, or earlier under storage pressure.
## Scheduled latest images
`POST /api/images/schedules`:
```json
{"name":"Savannah","minutes":5,"image":{"site":"KCLX","bbox":[-84,30,-78,35],"width":960,"height":640}}
```
Schedules produce latest PNGs, every 5โ1440 minutes, up to 12 schedules. Configure from Server & image API in the PWA or via JSON. The region and options persist across restart. The recorder remains independent; scheduling does not guarantee that a new NOAA scan exists at each interval.
- `GET /api/images/schedules`: configurations, latest job and actual scan metadata.
- `GET /api/images/schedules/ID/latest`: last completed cached PNG, including while the next is preparing. Returns 404 before first completion or after eviction.
- `DELETE /api/images/schedules/ID`: remove a schedule.
Scheduled outputs share the image cache; this is a bounded rolling collection, not permanent retention of every image. Download images elsewhere if permanent history is needed.
## Metadata and satellite
- `GET /api/frames?site=KCLX&product=reflectivity&tilt=0.5&minutes=120`: status and the newest two prepared frames, with observation times and source metadata. Add `latest=false` to prepare the full loop. Poll while loading. This remains the radar scan metadata endpoint.
- `GET /api/satellite/match?kind=infrared&time=2026-10-26T18:00:00Z`: closest advertised observation, signed `differenceSeconds` (satellite minus radar), large-gap flag above 5 minutes. A 15-minute maximum gap prevents stale overlays.
- `GET /api/satellite/image?kind=infrared&time=...&bbox=-84,30,-78,35&width=960&height=640`: explicit available satellite time, PNG. Kind is visible or infrared.
- `GET /api/server`: queue, worker, processing metrics, independent cache sizes and schedule/job status. Protected by the same authentication as other APIs.
- `/health`: minimal unauthenticated container liveness only.
NOAA satellite service retains a rolling window (about 8 hours observed during release validation). The app does not claim multi-day satellite history. Visible imagery is dark at night; infrared works day/night. These are satellite images, not a quantitative cloud-fraction mask. GOES mosaics have a nominal published frame time; pixels from different source scans may have additional timing variation.