World War Watcher API — Developer Documentation
Everything on the dashboard is available as JSON from https://api.worldwarwatcher.com. There is no API key, no signup, and no developer account—the API CORS is open (*), responses are cached at the edge, and all content is licensed CC BY-NC 4.0. For commercial use, get in touch.
curl 'https://api.worldwarwatcher.com/api/v1/search?q=hormuz&limit=3'
curl 'https://api.worldwarwatcher.com/api/v1/score'
curl -H 'Accept: text/markdown' https://worldwarwatcher.com/commentary/day-175ENDPOINTS
All paths are relative to https://api.worldwarwatcher.com. Search syntax, intents, and the citation object are documented in full on the Query API page; this table is the index.
| Endpoint | Returns | Refresh |
|---|---|---|
| GET /api/v1/search?q= | BM25 full-text search over ~1,500 editorial passages; every result carries a citation object with a stable anchor URL. | each deploy |
| GET /api/v1/search/answer?q= | Intent-classified, templated answer (dispatch day, latest dispatch, region bio, etymology, tradition, silences). Never LLM-generated. | each deploy |
| GET /api/v1/search/health | Index build timestamp and per-surface passage counts. | — |
| GET /api/v1/score | Composite escalation score, alert level, war day, 9-factor breakdown. | on each Mazkir merge |
| GET /api/v1/score/history?days=7 | Daily score snapshots. | daily |
| GET /api/v1/badge?style=phosphor&metric=score | Embeddable SVG badge with the Tanit sigil (`metric=day|score|alert`). | 15 min cache |
| GET /api/v1/econ | 61 tickers across 8 groups with 30-day history, pre-war baseline, and percentage deltas. | 15 min |
| GET /api/v1/infra | 10 cloud services, 3 latency probes, Iran connectivity consensus, battle damage assessment. | 10 min |
| GET /api/v1/ordnance | Weapon stockpiles, burn rates, interceptor status, depletion projections. | 6 h |
| GET /api/v1/oil-supply | EIA WPSR inventories, SPR fill, refinery utilization, Brent-WTI spread. | 6 h |
Static JSON (timeline, sources, globe geometry, cables, corridor risk) is served from worldwarwatcher.com/data/*.json; see the research page for the full file catalog.
DISCOVERY
- /api/openapi.json — OpenAPI 3.1 (also at
https://api.worldwarwatcher.com/openapi.json). - https://api.worldwarwatcher.com/.well-known/api-catalog — RFC 9727 linkset.
- https://api.worldwarwatcher.com/ — JSON index of every endpoint.
- /llms.txt, /skill.md, /AGENTS.md, /agent-permissions.json — agent-facing manifests.
- HTML
<link rel="service-desc">on every page points at the OpenAPI document.
RATE LIMITS
60 requests per minute per IP on every public endpoint, enforced at the edge. Every response carries the IETF draft rate-limit policy header; a rejected request adds the current state and a legacy Retry-After.
RateLimit-Policy: "default";q=60;w=60 # on every response
RateLimit: "default";r=0;t=60 # only on 429
Retry-After: 60 # only on 429The limiter reports only pass/fail, so the remaining count is advertised only when it is known to be zero. Responses are cacheable (Cache-Control: public, max-age=300–900); cache them and you will rarely approach the limit.
VERSIONING & DEPRECATION POLICY
/api/v1/is the canonical prefix. The unversioned/api/paths are permanent aliases of v1 and will not be removed.- Additive changes (new fields, new endpoints, new query parameters) ship within v1 without notice; consumers must tolerate unknown fields.
- Breaking changes—removed or renamed fields, changed semantics—ship only under a new major prefix (
/api/v2/). v1 keeps serving. - Before any endpoint is retired it emits RFC 9745
DeprecationandSunsetheaders plus aLink rel="deprecation"to a migration note, with a sunset date at least 90 days out. The changelog below is updated first. - The OpenAPI document's
info.versiontracks the schema; endpoint paths track the major version.
ERROR MODEL
Every error is RFC 9457 application/problem+json with Cache-Control: no-store. The code member is stable and safe to switch on; error is kept for pre-v1 consumers. Search errors add syntax_help.
{
"type": "https://worldwarwatcher.com/developers#errors-missing_query",
"title": "Bad Request",
"status": 400,
"detail": "Missing required query parameter q.",
"instance": "/api/v1/search",
"code": "missing_query",
"error": "Missing required query parameter q.",
"syntax_help": "Terms are ANDed; use \"double quotes\" for exact phrases. …"
}| Status | code | Meaning |
|---|---|---|
| 400 | missing_query | Required `q` parameter absent or blank. |
| 400 | query_too_long | `q` exceeds 500 characters. |
| 400 | invalid_surface | `surface` is not one of dispatches, regions, library. |
| 400 | query_parse_failed | Query rejected by the syntax parser (see `syntax_help`). |
| 400 | fts_parse_failed | Query rejected by FTS5 (see `syntax_help`). |
| 404 | not_found | No endpoint at this path; body lists `endpoints` and `docs`. |
| 405 | method_not_allowed | Only GET (and OPTIONS preflight) is accepted; `Allow` header set. |
| 429 | rate_limit_exceeded | 60 requests/minute per IP exceeded; `Retry-After: 60`. |
| 500 | answer_failed | Answer retrieval failed upstream. |
| 502 | score_corrupt | Stored score failed validation. |
| 503 | score_unavailable | Score not yet published for this deployment. |
MARKDOWN FOR AGENTS
Every HTML page negotiates to Markdown. Send Accept: text/markdown and the response is Content-Type: text/markdown; charset=utf-8 with Vary: Accept; or fetch the twin directly by appending .md (/commentary/day-175.md, /regions/iran.md, /methodology.md). Dispatch twins are the verbatim source Markdown, frontmatter included. A 404 under the Markdown header returns a Markdown body with recovery links.
CLI
wwatcher is a Typer/Rich terminal client (score, timeline <query> over FTS5, ask <question>). It is not yet on PyPI; install from source:
uv tool install "git+https://github.com/tdimino/worldwarwatcher#subdirectory=cli"
wwatcher score
wwatcher timeline "kharg island"MCP
There is no MCP server yet. The /api/v1/search and /answer endpoints are deterministic and keyless, so a single tool wrapping them is a ten-line adapter; when an official server ships it will be announced here and in llms.txt.
CHANGELOG
- 2026-08-21 —
/api/v1/prefix introduced; unversioned paths become permanent aliases. RFC 9457 errors and IETF rate-limit headers on search and score APIs. API root index,/openapi.json, RFC 9727 catalog. Markdown content negotiation site-wide. This page. - 2026-07 — Query API (
/api/search,/answer) launched over D1/FTS5. - 2026-05 — Score API and SVG badge.
- 2026-03 — Econ, infra, ordnance, and oil-supply Workers with KV-backed caching.