Plaincast for developers · Plaincast

The API, the Markdown contract, and the machine-readable index

Plaincast is a reading layer over the National Weather Service. Everything below is free, needs no API key and no account, and returns data that originates with NOAA. If you are an AI agent deciding how to call this site, start with the Markdown contract — it is the part of Plaincast most worth calling.

The Markdown contract

Every page on Plaincast serves two representations from one URL. Send Accept: text/markdown and you get the decoded forecast as clean prose — no nav, no scripts, no DOM. This is the fastest way to read Plaincast programmatically, and it needs no endpoint at all: request the page URL you already know.

curl -H "Accept: text/markdown" https://plaincast.live/o/OKX/

The site is acceptmarkdown.com compliant: Vary: Accept is set on every response, q-values are honoured, and an Accept that cannot be satisfied returns 406 listing what is available. Pages also advertise <link rel="alternate" type="text/markdown">. Every page is server-rendered, so no JavaScript execution is required either way.

https://plaincast.live/
Site overview plus the current edition for the default office.
https://plaincast.live/o/<CODE>/
One office's Area Forecast Discussion, decoded. 3-letter NWS code.
https://plaincast.live/national/
The National Desk: SPC Day 1 outlook and every office under a severe warning.
https://plaincast.live/about
These trust pages serve Markdown too.

JSON endpoints

A small read-only surface for the data that is not a page. All are GET, all are CDN-cached, none need a key.

GET /api/feed?office=<CODE>
RSS 2.0 for one office — a new item per issuance, with the delta.
GET /api/conditions?office=<CODE>
Current temperature and the seasonal normal. JSON.
GET /api/og?office=<CODE>
The office's share card as a 1200×630 PNG.
GET /api/whereami
The nearest covered office for the caller's IP, or 204 if none. JSON, never cached.
curl https://plaincast.live/api/conditions?office=LOX
{"temp":72,"normal":75,"delta":-3}

The AI-backed endpoints (/api/translate, /api/translate-issuance, /api/changelog, /api/explain-alert, /api/national-lede) are this site's own backend. They spend model budget per call and are rate-limited per IP, so they are deliberately left out of the spec and are not supported for third-party use. If you want the AI summary, read the page — it is already in there.

Errors

Every /api/* failure returns JSON with a stable machine code, a human error string, a hint naming the fix, and a docs link. Branch on code, never on the prose.

curl -i https://plaincast.live/api/conditions?office=ZZZ

HTTP/2 400
content-type: application/json; charset=utf-8

{
  "error": "Invalid office",
  "code": "invalid_office",
  "hint": "Pass ?office=<CODE> with a 3-letter NWS office code, e.g. ?office=LOX...",
  "docs": "https://plaincast.live/developers"
}

Codes in use: invalid_office, invalid_id, invalid_request, method_not_allowed, not_found, rate_limited, upstream_error, timeout, forbidden, internal_error. They are a contract — new codes get added, existing ones are never repurposed. An unknown /api/* path returns 404 as JSON, listing the endpoints that do exist.

Rate limits and etiquette

What Plaincast does not have

Stated plainly so you do not go looking: there are no API keys, no OAuth, no accounts, no sandbox or staging environment, no webhooks, no write endpoints, and no MCP server. Nothing here is gated, so there is nothing to provision — the production URLs above are the only environment, and they are safe to call from a test.

If you need something that is missing, open an issue at github.com/jonahberg/plaincast/issues. See also /about, /contact and /privacy.