World Pulse Open app

Free public API

Static JSON files, regenerated every one to four hours. No key, no sign-up, and CORS is open, so you can call it straight from a browser or mobile app. Base path: /api/v1/. Machine-readable spec: openapi.json.

curl -s https://YOUR-SITE/api/v1/conflicts.json | jq '.data.theaters[] | {name, status, trend, intensity}'
curl -s https://YOUR-SITE/api/v1/brief.json | jq '.data | {headline, source}'

Endpoints

PathReturns
brief.jsonWorld brief: headline, 4–6 bullets citing the stories they're based on, and what to watch next. source is ai (written by Claude) or rules (automated digest).
conflicts.jsonConflict tracker: every theater with intensity (0–100), status, trend, 24h/7-day report counts, daily history, signal counts, a situation analysis and the latest stories.
conflicts/{id}.jsonOne theater plus all its stories from the last 7 days. Ids are listed in index.json.
conflicts.xmlRSS feed of conflict reports.
latest.jsonMost recent 300 stories.
news.jsonCurated news items: the top events ranked by importance, each with its sources and translations (what the app shows).
all.jsonRolling archive of the last 7 days.
state.jsonTension index, mood, category and region breakdown, 7-day history, trending terms, conflict overview.
categories/{id}.json / .xmldeals, crises, conflict, disasters, humanitarian, economy, diplomacy, climate, health, tech.
regions/{id}.jsonafrica, asia, europe, middle-east, americas, oceania.
index.jsonDiscovery: endpoints, categories, regions, theaters, AI status, source health.
sources.jsonEvery feed with its status from the latest build.

Story fields

{
  "id": "3f1c0a9b2d4e5f60",
  "title": "…", "url": "https://publisher.example/story", "summary": "Short excerpt…",
  "image": "https://…/thumb.jpg",
  "source": { "id": "bbc-world", "name": "BBC News – World" },
  "published_at": "2026-10-11T11:42:00Z", "fetched_at": "2026-10-11T12:00:00Z",
  "categories": ["crises", "conflict"], "regions": ["europe"], "tone": "crisis",
  "theaters": ["russia-ukraine"],      // conflict theaters the story is about
  "severity": 3,                       // 0 not conflict … 5 mass-casualty / new war
  "signal": "escalation",              // escalation | de-escalation | humanitarian | diplomatic | none
  "insight": "One-line why-it-matters", // AI-written, or null
  "analysis": "ai",                    // "ai" (Claude) or "rules"
  "cluster": "3f1c0a9b2d4e5f60",       // lead story id of the same event
  "coverage": 4                        // outlets that covered the event
}

Languages

Every field above stays in English. Translations sit next to it in i18n objects keyed by language: de (German) and sr (Serbian, Cyrillic; the app makes Serbian Latin from it by transliteration). A missing language, or an empty i18n, means use the English. Publishers' headlines are never translated.

FieldContains
conflicts.json theaters[].i18n{"de": {"name", "description"}, "sr": {…}}; in index.json just the name, {"de": "Russland–Ukraine"}.
brief.json i18nAI briefs only: {"de": {"headline", "bullets": […], "watch"}}, where bullets[i] translates bullets[i].text. index.json ai.brief_translations lists the languages present.
theaters[].analysis.i18nAI summaries only: {"de": {"summary", "outlook", "developments": […]}}; a null part means show the English.
rule, mood_key, disclaimer_key, explanation_keyAutomated texts come with the counts and keys they were written from, so an app can write them in its own language: brief.json rule (active_conflicts, escalating, mood_key, watch) and analysis.rule (key, stories_24h, stories_7d, trend).
index.json revenue.plans[].i18n{"de": {"name", "blurb", "features": […], "cta"}}. Prices stay in USD.

The web app follows the browser language and can be switched in the header; add ?lang=en, de, sr or sr-Latn to a link to open it in that language.

Method

Collection. Public RSS/Atom feeds listed in config/sources.json. Only headlines, short excerpts and links are republished.

Rules. Topics, regions and conflict theaters are first tagged with transparent keyword rules (worldpulse/classify.py, config/conflicts.json), with severity and signal from word lists (worldpulse/conflicts.py).

AI. When enabled, Claude reviews new conflict-related stories once per build (every one to four hours) and replaces the rule values with its own judgement. It also writes the world brief and the situation summaries. Its output is constrained to a schema, validated, and labelled everywhere it appears. It can still make mistakes, so every claim links to its sources.

Intensity is the summed severity of a theater's reports over 24h, mapped to 0–100. The trend compares the last 24h with the theater's own baseline over the days the archive has observed. Both measure news coverage, not verified events or casualties.

Business use

The API stays free and keyless for everyone, including commercial projects. If your organisation relies on it, the Business plan ($49 a month on Ko-fi) includes everything in World Pulse Pro and adds priority support, receipts, and requests for new sources and conflict theaters.

Fair use

Always link to url and credit source.name. Please cache responses, because the data only changes with each build, every one to four hours.