Quick Start

Get up and running with the POLYCRISIS API in three steps.

01

Get your API key

Create an account from the dashboard, then mint keys in your account settings. Keys are prefixed pk_. Treat them like passwords — don’t embed them in client-side JavaScript.

02

Make your first call

Hit the /v1/crises endpoint to discover all tracked crisis theaters and their current status.

03

Explore endpoints

Use /v1/events for geolocated data, /v1/connections for cross-crisis links, /v1/scenarios for probability analysis, or /v1/signals for composite alerts.

curl
Python
curl
# Discover all crises
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/crises"

# Get Iran military events
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/events?crisis=iran&type=military&limit=5"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}

# Discover all crises
crises = requests.get(
    "https://polycrisis.world/api/v1/crises",
    headers=headers
).json()

# Get Iran military events
events = requests.get(
    "https://polycrisis.world/api/v1/events",
    headers=headers,
    params={"crisis": "iran", "type": "military", "limit": 5}
).json()

for event in events["events"]:
    print(f"{event['event_type']}: {event['title']}")
Rate limits by plan: Developer ($79/mo) is 5,000 req/day at 60 req/min. See Rate Limits for details.

Authentication

All API requests require a Bearer token in the Authorization header. API keys are prefixed pk_. You can generate keys from your dashboard after creating an account. Treat keys like passwords — never commit them to source control or embed them in client-side code.

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  https://polycrisis.world/api/v1/events
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
response = requests.get(
    "https://polycrisis.world/api/v1/events",
    headers=headers
)
data = response.json()

Include this header with every request. Requests without a valid key receive a 401 Unauthorized response. Keys are tied to a pricing tier that determines rate limits and endpoint access.


Base URL

All API endpoints are served from a single base URL:

https://polycrisis.world/api/v1/

All requests must use HTTPS. HTTP requests will be redirected. API versioning is included in the path — the current version is v1.


Response Format

Successful responses are flat JSON objects whose top-level keys are endpoint-specific. There is no envelope — the requested payload is the response body. Endpoints that paginate include a meta object alongside their primary key (e.g. events + meta for /events); endpoints that don't paginate omit it. Rate-limit information is delivered via response headers (see Rate Limits below), not in the body.

Example: /v1/events

json
{
  "events": [
    { "id": "evt_12345", "crisis": "iran", "event_type": "military", /* ... */ }
  ],
  "meta": {
    "total": 1234,
    "returned": 100,
    "offset": 0,
    "limit": 100
  }
}

Example: /v1/crises

json
{
  "crises": [
    { "id": "iran", "name": "Iran", /* ... */ }
  ],
  "last_updated": "2026-04-07T15:30:00Z"
}

Error responses return a single error field with a human-readable string. HTTP status codes carry the machine-readable signal — check the status before reading the body.

json
{
  "error": "Rate limit exceeded",
  "limit": 15,
  "plan": "sandbox",
  "retry_after": 60
}

Rate Limits

Rate limits are enforced per API key. The window depends on which key you use: the public sandbox key uses a 60-second sliding window per IP, while paid keys use a daily quota that resets at UTC midnight. Every response includes rate-limit headers so you can track your usage programmatically.

Response Headers

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the active window for your tier.
X-RateLimit-RemainingRequests remaining in the current window.
X-RateLimit-ResetUnix timestamp (seconds since epoch) when the active window resets. For sandbox this is roughly now+60s; for paid it is the next UTC midnight.
Retry-AfterSet on 429 responses only. Number of seconds to wait before retrying.

Tier Limits

TierQuotaWindowNotes
Developer ($79/mo)5,000per dayFull /api/v1/: events, scenarios, correlations, markets, signals, analogs, patterns. Webhooks, SSE streaming. Unlimited keys. 60 req/min.

When you exceed your rate limit, the API returns 429 Too Many Requests. The Retry-After header tells you how many seconds to wait; the X-RateLimit-Reset header gives an absolute timestamp. Always honor whichever is more conservative.


Errors

The API uses standard HTTP status codes. The status code is the canonical machine-readable signal — check it before parsing the body. Error response bodies are flat JSON objects with an error string and, depending on the error, additional context fields (limit, plan, retry_after, valid, etc.).

StatusWhenHow to recover
400Missing required query parameter, invalid value, or malformed request body.Read the error field for the specific issue. Fix and retry.
401Missing or invalid Authorization: Bearer header.Provide a valid API key from your dashboard.
404Unknown endpoint or resource not found.Check the URL against this docs page or openapi.json.
429Rate limit exceeded for your key.Wait for the time in Retry-After or X-RateLimit-Reset, then retry.
500Server-side error processing the request.Retry with exponential backoff. If persistent, contact support.
503Database temporarily unavailable.Retry after a few seconds.

Examples

400 Bad Request — missing required parameter:

json
{
  "error": "type and crisis query params are required"
}

401 Unauthorized:

json
{
  "error": "Unauthorized. Provide Authorization: Bearer <api_key> header."
}

429 Rate Limited:

json
{
  "error": "Rate limit exceeded",
  "limit": 15,
  "plan": "sandbox",
  "retry_after": 60
}

500 Internal:

json
{
  "error": "Internal server error"
}

GET /v1/crises All

Discovery endpoint. Returns all tracked crisis theaters with current status, event counts, intensity scores, geographic bounds, and center coordinates. This is the entry point to the API — use the id field to query all other endpoints.

Parameters

None required.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/crises"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
response = requests.get(
    "https://polycrisis.world/api/v1/crises",
    headers=headers
)
crises = response.json()["crises"]
for c in crises:
    print(f"{c['emoji']} {c['name']}: intensity {c['intensity']}")

Response

json
{
  "crises": [
    {
      "id": "iran",
      "name": "Iran",
      "emoji": "🇮🇷",
      "color": "#dc2626",
      "status": "active",
      "event_count": 847,
      "latest_event": "2026-03-21T14:23:00Z",
      "intensity": 7.2,
      "center": { "lat": 32.4, "lng": 53.7 },
      "bounds": { "lat_min": 12, "lat_max": 42, "lng_min": 28, "lng_max": 66 }
    }
  ],
  "last_updated": "2026-03-21T14:30:00Z",
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": { "count": 7 }
}

GET /v1/events All

Retrieve geolocated crisis events. Events are extracted from 150+ sources every 15 minutes using AI, with coordinates verified by gazetteer lookup and geocorrection. Supports full-text search and offset pagination.

Parameters

ParameterTypeRequiredDescription
crisisstringNoCrisis theater: iran, ukraine, gaza, scs, climate, usa (United States), agi. Use /v1/crises for the full list. Omit for all.
typestringNoSingle event type: military, naval, nuclear, political, economic, protest, humanitarian, enforcement, climate, cyber, news. Note: economic covers oil prices, sanctions, trade disruptions, supply chain events, and market impacts. Previously classified as political.
cluster_idstringNoFilter events by story cluster. Returns only events in the specified cluster.
sincestringNoISO 8601 timestamp. Return events on or after this time.
untilstringNoISO 8601 timestamp. Return events before this time.
min_confidencenumberNoMinimum confidence score (0–1). Also accepts confidence_min. Default: 0.
qstringNoFull-text search query across title and description. Also accepts search.
sortstringNoSort order: chronological (default), newest, or confidence.
limitintegerNoMax events to return. Default: 100, range 1–500.
offsetintegerNoOffset for pagination. Default: 0. Combine with meta.total in the response.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/events?crisis=scs&type=naval&since=2026-03-15T00:00:00Z&limit=50"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
response = requests.get(
    "https://polycrisis.world/api/v1/events",
    headers=headers,
    params={
        "crisis": "scs",
        "type": "naval",
        "since": "2026-03-15T00:00:00Z",
        "limit": 50
    }
)
events = response.json()["events"]
for event in events:
    print(f"{event['event_type']}: {event['title']}")

Response

json
{
  "events": [
    {
      "id": "evt_7823",
      "crisis": "scs",
      "event_type": "naval",
      "title": "Philippine Coast Guard reports water cannon incident near Scarborough Shoal",
      "description": "Chinese coast guard vessels deployed water cannons against Philippine resupply mission near Scarborough Shoal.",
      "lat": 15.228,
      "lng": 117.764,
      "timestamp": "2026-03-15T08:23:00Z",
      "source": "ai",
      "source_url": "https://www.rappler.com/nation/...",
      "source_name": "Rappler",
      "confidence": 0.92,
      "cluster_id": "story_scs_8842"
    }
  ],
  "meta": {
    "total": 847,
    "returned": 50,
    "offset": 0,
    "limit": 50,
    "generated_at": "2026-03-21T14:30:00Z"
  },
  "generated_at": "2026-03-21T14:30:00Z"
}

Response Fields

The source field indicates the ingestion method (ai or static). For the news outlet name, use source_name.

FieldTypeDescription
idstringUnique event ID (prefixed with evt_, e.g. "evt_7823").
crisisstringCrisis theater the event belongs to.
event_typestringCanonical type: military, naval, nuclear, political, economic, protest, humanitarian, enforcement, climate, cyber, news.
titlestringShort headline.
descriptionstringLonger description of the event.
latnumberLatitude (WGS 84).
lngnumberLongitude (WGS 84).
timestampstringISO 8601 timestamp of when the event occurred (e.g. "2026-03-15T08:23:00Z").
sourcestringIngestion method: ai (extracted by AI) or static (manually seeded). Not the outlet name.
source_urlstringURL of the original article.
source_namestringName of the news source (e.g. “Reuters”, “BBC”). Use this instead of source for the outlet name.
confidencenumberComposite confidence score (0–1).
cluster_idstring | nullStory-level grouping ID. Events about the same story share a cluster_id (e.g. "story_iran_12345"). Filter with ?cluster_id=.

GET /v1/event-stats All

Track record (Brier calibration) for an event type within a crisis. Returns per-ticker UP-rate, average pct move, and Brier score across the 15m, 1h, 4h, and 1d horizons. Lookback: 90 days. Response cached server-side for 6 hours.

Why Brier?

Brier score measures how well calibrated the system's directional predictions are. Lower is better. A coin flip = 0.25; a well-calibrated forecaster typically scores around 0.15. We compute Brier per (event type × crisis × ticker × horizon) using a rolling self-referential baseline: the predicted UP probability for an event is the rolling UP-rate of prior events of the same type. Cells with fewer than 5 events suppress the Brier number to avoid meaningless precision.

Move thresholds: ±0.3% for equities, ±0.5% for commodities (CL=F, NG=F, BZ=F). Smaller moves count as NO_MOVE and are treated as not-UP for the binary Brier target.

Parameters

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/event-stats?type=military&crisis=iran&breakdown=full"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
response = requests.get(
    "https://polycrisis.world/api/v1/event-stats",
    params={"type": "military", "crisis": "iran", "breakdown": "full"},
    headers=headers
)
stats = response.json()
for ticker, data in stats["tickers"].items():
    h1h = data["horizons"]["1h"]
    print(f"{ticker} 1h: UP-rate {h1h['up_rate']*100:.0f}%, Brier {h1h['brier']}")

Response

json
{
  "type": "military",
  "crisis": "iran",
  "n": 47,
  "tickers": {
    "CL=F": {
      "n": 47,
      "horizons": {
        "15m": { "n": 45, "up_rate": 0.58, "avg_move_pct": 0.003, "brier": 0.21 },
        "1h":  { "n": 45, "up_rate": 0.62, "avg_move_pct": 0.008, "brier": 0.18 },
        "4h":  { "n": 44, "up_rate": 0.55, "avg_move_pct": 0.011, "brier": 0.22 },
        "1d":  { "n": 44, "up_rate": 0.49, "avg_move_pct": 0.004, "brier": 0.27 }
      }
    }
  },
  "samples": [
    {
      "id": 12345,
      "label": "IRGC strike on convoy",
      "source_url": "https://example.com/article",
      "source_name": "Reuters",
      "t": 1740000000,
      "outcomes": {
        "CL=F": {
          "15m": { "movement": "UP", "pct": 0.004 },
          "1h":  { "movement": "UP", "pct": 0.009 }
        }
      }
    }
  ],
  "as_of": "2026-04-07T15:30:00Z"
}

GET /v1/connections All

Cross-crisis connections with real-time intensity tracking and cluster-driven alignment scoring. Each connection is enriched from three signal layers: event-detected (Haiku pipeline analysis), cluster-boosted (embedding space proximity), and scenario-derived (scenario tree parent links, including systemic crises).

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to connections involving this crisis
limitintegerNoMax results (1–50). Default: 20

Request

curl
Python
curl
curl https://polycrisis.world/api/v1/connections?crisis=iran \
  -H "Authorization: Bearer pk_YOUR_KEY"
python
resp = requests.get(
    "https://polycrisis.world/api/v1/connections",
    params={"crisis": "iran"},
    headers={"Authorization": "Bearer pk_YOUR_KEY"}
)

Response

json
{
  "connections": [
    {
      "source_crisis": "iran",
      "target_crisis": "gaza",
      "strength": 0.82,
      "intensity": {
        "level": "elevated",
        "event_velocity": 4.2,
        "baseline_velocity": 1.1,
        "trend": "rising",
        "window": "7d"
      },
      "cluster_alignment": 0.78,
      "mechanisms": ["Hezbollah/Hamas axis", "Regional military escalation"],
      "evidence_count": 14,
      "sources": ["event_detected", "cluster_boosted"]
    }
  ],
  "meta": {
    "total": 12,
    "signal_layers": ["event_detected", "cluster_boosted", "scenario_derived"]
  }
}

GET /v1/scenarios All

Returns AI-generated scenario assessments for a crisis theater. Each scenario includes a probability integer 0–100, a band label (REMOTE/UNLIKELY/PLAUSIBLE/LIKELY/IMMINENT/CONFIRMED), the most recent justification, and the URL that moved it last. Assessments are generated by Claude Sonnet and refreshed every few hours based on the live event stream.

Parameters

ParameterTypeRequiredDescription
crisisstringNoCrisis theater (e.g. iran). If omitted, returns a map keyed by crisis.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/scenarios?crisis=iran"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/scenarios",
    headers=headers,
    params={"crisis": "iran"}
).json()

for s in data["scenarios"]:
    print(f"{s['title']}: {s['probability']}% [{s['band']}]")

Response

json
{
  "crisis": "iran",
  "scenarios": [
    {
      "id": "iran_strike",
      "title": "US/Israel strike on nuclear facilities",
      "description": "Kinetic action targeting enrichment sites.",
      "probability": 25,
      "previous_probability": 18,
      "band": "UNLIKELY",
      "color": "#f97316",
      "justification": "IAEA non-compliance finding and Israeli cabinet leaks indicate rising strike risk.",
      "source_url": "https://www.reuters.com/...",
      "cluster_momentum": {
        "growth_rate": 0.42,
        "coherence_delta": 0.81,
        "alignment_score": 0.67
      }
    }
  ],
  "intensity": { "value": 7.2, "band": "high" },
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": { "count": 8 }
}

GET /v1/scenarios/{id} All

Get a single scenario with its full ancestry (path to root) and descendants (child branches in the scenario tree).

Parameters

ParameterTypeRequiredDescription
id requiredstringYesScenario node ID (e.g., iran_hormuz)

Request

curl
Python
curl
curl https://polycrisis.world/api/v1/scenarios/iran_hormuz \
  -H "Authorization: Bearer pk_YOUR_KEY"
python
resp = requests.get(
    "https://polycrisis.world/api/v1/scenarios/iran_hormuz",
    headers={"Authorization": "Bearer pk_YOUR_KEY"}
)

Response

json
{
  "scenario": {
    "id": "iran_hormuz",
    "crisis": "iran",
    "label": "Strait of Hormuz closure",
    "risk": "plausible",
    "probability": 35
  },
  "ancestors": [
    { "id": "iran_escalation", "label": "Military escalation" }
  ],
  "descendants": [
    { "id": "iran_oil_shock", "label": "Global oil price shock" }
  ],
  "path": ["iran_escalation", "iran_hormuz"]
}

GET /v1/scenarios/tree All

Full scenario tree with all nodes. Confirmed events at center, speculative futures branching outward through risk levels: confirmed → high → likely → plausible → speculative → remote.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter tree to nodes from this crisis (includes cross-crisis connections)

Request

curl
Python
curl
curl https://polycrisis.world/api/v1/scenarios/tree?crisis=iran \
  -H "Authorization: Bearer pk_YOUR_KEY"
python
resp = requests.get(
    "https://polycrisis.world/api/v1/scenarios/tree",
    params={"crisis": "iran"},
    headers={"Authorization": "Bearer pk_YOUR_KEY"}
)

Response

json
{
  "tree": {
    "nodes": [
      {
        "id": "iran_hormuz",
        "crisis": "iran",
        "label": "Strait of Hormuz closure",
        "risk": "plausible",
        "probability": 35,
        "parent": "iran_escalation"
      }
    ]
  },
  "meta": {
    "total_nodes": 142,
    "updated_at": "2026-03-28T06:00:00Z"
  }
}

GET /v1/scenarios/paths All

Ranked escalation chains from confirmed events through to speculative/remote outcomes. Each path traces a sequence of scenarios from center to edge of the tree.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to paths from this crisis

Response

json
{
  "paths": [
    {
      "nodes": [
        { "id": "iran_strike_confirmed", "risk": "confirmed" },
        { "id": "iran_retaliation", "risk": "likely" },
        { "id": "iran_hormuz", "risk": "plausible" }
      ],
      "terminal_risk": "plausible",
      "terminal_probability": 35
    }
  ]
}

GET /v1/scenarios/changes All

Recent tree mutations — nodes added, removed, or risk levels changed.

Parameters

ParameterTypeRequiredDescription
sincestringNoISO date. Default: last 24 hours.
crisisstringNoFilter to changes in this crisis

Response

json
{
  "changes": [
    {
      "node_id": "iran_hormuz",
      "type": "risk_changed",
      "old_value": "speculative",
      "new_value": "plausible",
      "changed_at": "2026-03-28T06:00:00Z"
    }
  ]
}

GET /v1/scenarios/history All

Probability change history for scenarios over time. Track how scenario likelihoods have evolved.

Parameters

ParameterTypeRequiredDescription
crisis requiredstringYesCrisis to get history for
scenario_idstringNoFilter to specific scenario
daysintegerNoLookback window. Default: 30

Response

json
{
  "history": [
    {
      "scenario_id": "iran_hormuz",
      "title": "Strait of Hormuz closure",
      "data_points": [
        { "date": "2026-03-01", "probability": 25 },
        { "date": "2026-03-15", "probability": 35 }
      ]
    }
  ]
}

GET /v1/scenarios/ripple All

Scenario-to-scenario chain reactions across crises. Shows how one scenario triggering could ripple into scenarios in other crisis theaters. This is the scenario-level equivalent of crisis-level connections.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to ripples from this crisis
scenario_idstringNoShow ripples from a specific scenario

Response

json
{
  "ripples": [
    {
      "src_crisis": "iran",
      "src_scenario": "iran_hormuz",
      "src_title": "Strait of Hormuz closure",
      "tgt_crisis": "climate",
      "tgt_scenario": "climate_energy_shock",
      "tgt_title": "Global energy price shock",
      "mechanism": "Oil supply disruption triggers energy crisis",
      "weight": 0.75
    }
  ]
}

GET /v1/patterns All

Returns all spatial-temporal event clusters (patterns) detected by DBSCAN clustering across the event corpus. Each cluster represents a group of related events that share geographic and thematic proximity.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter clusters involving this crisis theater.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/patterns"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/patterns",
    headers=headers
).json()

for p in data["patterns"]:
    print(f"{p['label']}: {p['event_count']} events (coherence {p['coherence_score']})")

Response

json
{
  "patterns": [
    {
      "id": "clst_0",
      "label": "Eastern Mediterranean Military Buildup",
      "description": "Cluster of military and naval events across Gaza and Iran theaters.",
      "crises": ["gaza", "iran"],
      "event_count": 47,
      "coherence_score": 0.82,
      "top_events": ["IDF airstrike Khan Younis", "Iran proxy naval incident"]
    }
  ],
  "meta": { "count": 12 },
  "generated_at": "2026-03-21T14:30:00Z"
}

GET /v1/patterns/{cluster_id} All

Deep dive into a specific event cluster. Returns all events in the cluster, crisis breakdown, and event type distribution.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/patterns/clst_0"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/patterns/clst_0",
    headers=headers
).json()

cluster = data["cluster"]
print(f"{cluster['label']}: {cluster['event_count']} events")
for event in cluster["events"]:
    print(f"  {event['event_date']}: {event['title']}")

Response

json
{
  "cluster": {
    "id": "clst_0",
    "label": "Eastern Mediterranean Military Buildup",
    "description": "Cluster of military and naval events across Gaza and Iran theaters.",
    "crises": ["gaza", "iran"],
    "event_count": 47,
    "type_breakdown": { "military": 22, "naval": 15 },
    "events": [
      {
        "id": 1234,
        "title": "IDF strikes southern Gaza",
        "crisis": "gaza",
        "event_type": "military",
        "event_date": "2026-03-20T00:00:00Z"
      }
    ]
  }
}

GET /v1/patterns/similar All

Vector-similarity search over historical events. Given an event type and region, returns the closest matches from the archive using embedding distance.

Parameters

ParameterTypeRequiredDescription
event_type requiredstringYesCanonical event type (e.g. military, naval).
regionstringNoCrisis theater to bias the search toward.
lookbackintegerNoLookback in days for the candidate pool. Default: 180.
thresholdnumberNoMinimum cosine similarity (0–1) to return. Default: 0.7.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/patterns/similar?event_type=military&region=iran"
python
import requests
data = requests.get(
    "https://polycrisis.world/api/v1/patterns/similar",
    headers={"Authorization": "Bearer $POLYCRISIS_KEY"},
    params={"event_type": "military", "region": "iran"}
).json()

Response

json
{
  "query": { "event_type": "military", "region": "iran", "lookback": 180, "threshold": 0.7 },
  "matches": [
    { "id": 8231, "label": "IRGC drone strike on oil facility", "event_date": "2025-11-04", "similarity": 0.91 }
  ],
  "generated_at": "2026-03-21T14:30:00Z"
}

GET /v1/analogs All

Find historical analogs to current crisis conditions. Returns the top past periods with similar event patterns, along with what happened next — cascading effects, market outcomes, and scenario probability changes.

Parameters

ParameterTypeRequiredDescription
crisis requiredstringYesCrisis theater to find analogs for.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/analogs?crisis=scs"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/analogs",
    headers=headers,
    params={"crisis": "scs"}
).json()

for a in data["analogs"]:
    print(f"{a['period']}: {a['title']} (similarity {a['similarity']:.2f})")

Response

json
{
  "crisis": "scs",
  "current_type_mix": { "naval": 18, "military": 6, "political": 4 },
  "current_event_count": 28,
  "analogs": [
    {
      "period": "2025-03-08 to 2025-03-15",
      "similarity": 0.89,
      "title": "PLAN exercises near Scarborough Shoal",
      "event_count": 12,
      "outcome": "De-escalation after 9 days. USN carrier redeployed.",
      "market_outcome": { "CL=F": "+1.8%", "TSM": "-4.2%" },
      "resolution_days": 9
    }
  ],
  "historical_conflicts": [],
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": { "top_k": 10 }
}

GET /v1/actors All

Entity-centric intelligence. Tracks organizations, governments, military groups, and key individuals across all crisis theaters. Shows who is active, where they appear, and whether their activity is rising or falling.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to actors in this crisis
limitintegerNoMax results (1–50). Default: 20

Response

json
{
  "actors": [
    {
      "name": "IRGC",
      "crises": ["iran", "gaza"],
      "event_count_7d": 12,
      "event_count_30d": 45,
      "trend": "rising",
      "last_seen": "2026-03-28T14:30:00Z",
      "primary_event_types": ["military", "naval"]
    }
  ],
  "meta": { "total": 15 }
}

GET /v1/actors/{name} All

Deep profile for a specific entity. Event timeline, crisis presence, and co-occurring actors.

Response

json
{
  "name": "IRGC",
  "crises": ["iran", "gaza"],
  "event_count": 45,
  "timeline": [
    {
      "id": 4521,
      "crisis": "iran",
      "event_type": "military",
      "date": "2026-03-28T14:30:00Z"
    }
  ],
  "connections": [
    { "name": "Hezbollah", "co_occurrences": 18 }
  ]
}

GET /v1/hotspots All

Geographic convergence zones where multi-crisis activity concentrates. Uses spatial clustering to identify areas where events from different crises overlap geographically.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to hotspots in this crisis
daysintegerNoLookback window (1–90). Default: 7
limitintegerNoMax results (1–25). Default: 10

Response

json
{
  "hotspots": [
    {
      "id": "hs_0",
      "name": "Strait of Hormuz",
      "center": { "lat": 26.5, "lng": 56.2 },
      "radius_km": 85,
      "crises": ["iran", "usa"],
      "event_count": 18,
      "dominant_types": ["naval", "military"],
      "trend": "heating"
    }
  ],
  "meta": { "total": 8, "days": 7 }
}

GET /v1/anomalies All

Events that don't fit established patterns. Embedding-space outliers — events whose semantic content is far from any identified cluster. Anomalies are either noise or early signals of emerging dynamics that existing analysis doesn't capture yet.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter to anomalies in this crisis
sinceintegerNoLookback in days (1–30). Default: 7
limitintegerNoMax results (1–25). Default: 10

Response

json
{
  "anomalies": [
    {
      "event": {
        "id": 4521,
        "crisis": "iran",
        "event_type": "cyber",
        "label": "Unexplained communications blackout in Isfahan",
        "date": "2026-03-27T08:15:00Z"
      },
      "deviation_score": 8.4,
      "nearest_pattern": {
        "id": 3,
        "label": "Hormuz Naval Activity"
      }
    }
  ],
  "meta": { "total": 5, "days": 7 }
}

Markets endpoints

Three market-data endpoints are available under /v1/markets/*. They proxy the dashboard's internal market views into the v1 API surface. Accept crisis as the primary filter and return minute/hour/day bar data suitable for charting.

EndpointReturns
GET /v1/markets/coneForward uncertainty cone (price fan) around a key ticker for a crisis. Response includes ticker, current_price, sigma_daily, and a series array of upper/lower bounds by horizon.
GET /v1/markets/sensitivityPer-scenario ticker sensitivity estimates. Response keys each scenario ID to an array of {ticker, expected_move_pct, confidence}.
GET /v1/markets/eventsRecent crisis events annotated with the market move that followed them (useful for backtesting).

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/markets/cone?crisis=iran"
python
import requests
cone = requests.get(
    "https://polycrisis.world/api/v1/markets/cone",
    headers={"Authorization": "Bearer $POLYCRISIS_KEY"},
    params={"crisis": "iran"}
).json()

print(f"{cone['ticker']}: {cone['current_price']} (σ={cone['sigma_daily']:.2%})")

GET /v1/intensity All

Returns a calculated escalation intensity index for a crisis, plus a timeseries over the requested window. Derived from event frequency, type severity weighting, and cross-crisis connection activity. Useful for triggering alerts or dynamically weighting portfolio exposure when a crisis is heating up.

Parameters

ParameterTypeRequiredDescription
crisisstringYesCrisis theater (e.g. scs, iran).
windowintegerNoNumber of days of history to include. Default: 30, max: 365.
granularitystringNoBucket size for the timeseries: day (default) or week. Also accepts bucket.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/intensity?crisis=scs&window=14"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/intensity",
    headers=headers,
    params={"crisis": "scs", "window": 14}
).json()

current = data["current_index"]
print(f"Intensity: {current['value']} ({current['band']})")
print(f"7-day delta: {current['delta_7d']}")

Response

json
{
  "crisis": "scs",
  "window_days": 14,
  "current_index": {
    "value": 7.8,
    "band": "high",
    "delta_7d": +0.6,
    "event_count": 38
  },
  "timeseries": [
    { "bucket": "2026-03-08", "index": 6.2, "event_count": 24 },
    { "bucket": "2026-03-15", "index": 7.1, "event_count": 31 },
    { "bucket": "2026-03-21", "index": 7.8, "event_count": 38 }
  ],
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": { "granularity": "day" }
}

GET /v1/indicators All

Returns 8 normalized (0–1) risk indicators for a crisis, plus a composite risk score. Covers escalation probability, event intensity, signal velocity, actor concentration, confidence drift, market contagion, narrative contagion, and anomaly detection. Cached for 15 minutes.

Parameters

ParameterTypeRequiredDescription
crisisstringOne of crisis or countryCrisis ID (e.g. iran, ukraine).
countrystringOne of crisis or countryCountry name (e.g. Turkey, Taiwan). Mapped to the relevant crisis.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/indicators?crisis=iran"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/indicators",
    headers=headers,
    params={"crisis": "iran"}
).json()

print(f"Composite risk: {data['composite_risk']}")
for name, ind in data["indicators"].items():
    print(f"  {name}: {ind['value']} ({ind['trend']})")

Response

json
{
  "crisis": "iran",
  "timestamp": "2026-04-20T12:00:00Z",
  "composite_risk": 0.52,
  "indicators": {
    "escalation_probability": { "value": 0.65, "trend": "rising", "period": "30d" },
    "event_intensity": { "value": 0.81, "trend": "stable", "period": "7d" },
    "signal_velocity": { "value": 0.43, "trend": "falling", "period": "3d" },
    "actor_concentration": { "value": 0.38, "trend": "stable", "period": "30d" },
    "confidence_drift": { "value": 0.45, "trend": "falling", "period": "7d" },
    "market_contagion": { "value": 0.72, "trend": "rising", "period": "30d" },
    "narrative_contagion": { "value": 0.55, "trend": "stable", "period": "30d" },
    "anomaly_index": { "value": 0.12, "trend": "stable", "period": "7d" }
  }
}

Indicator Descriptions

IndicatorSourceDescription
escalation_probabilityai_scenariosSeverity-weighted average of active scenario probabilities.
event_intensityevents7-day event rate vs 30-day baseline. >0.33 = acceleration.
signal_velocityevents3-day spike detection vs 30-day rolling average.
actor_concentrationeventsHHI of actor involvement. 1.0 = monopoly, ~0 = diffuse.
confidence_drifteventsChange in avg event confidence. <0.5 = increasing fog of war.
market_contagionmarket_dailyAvg |change_pct| of crisis-linked tickers. Higher = markets reacting.
narrative_contagioncrisis_connectionsStrength of spillover to other crisis theatres.
anomaly_indexeventsZ-score of event volume spikes vs 30-day baseline.

GET /v1/correlations Analyst+

Computes cross-crisis correlations between geopolitical event types and financial instruments, including statistical significance testing and average market moves. Requires the Developer plan.

Parameters

ParameterTypeRequiredDescription
crisis requiredstringYesCrisis theater to analyze.
event_typestringNoSource event type (e.g., naval, military). Omit for all types.
marketstringNoSingle market symbol to test (e.g., CL=F, TSM, GLD). Omit for the crisis’s default basket.
windowintegerNoLookback window in days. Default: 90.
windowsstringNoComma-separated post-event horizons to test (minutes). Default: 15,60,240,1440.

Request

curl
Python
curl
curl -H "Authorization: Bearer YOUR_ANALYST_KEY" \
  "https://polycrisis.world/api/v1/correlations?crisis=scs&event_type=naval&market=CL=F"
python
import requests

headers = {"Authorization": "Bearer YOUR_ANALYST_KEY"}
corr = requests.get(
    "https://polycrisis.world/api/v1/correlations",
    headers=headers,
    params={"crisis": "scs", "event_type": "naval", "market": "CL=F"}
).json()

for c in corr["correlations"]:
    print(f"{c['ticker']} @ {c['window_min']}m: r={c['correlation']:.2f}")

Response

json
{
  "crisis": "scs",
  "event_type": "naval",
  "window_days": 90,
  "correlations": [
    {
      "ticker": "CL=F",
      "window_min": 60,
      "correlation": 0.73,
      "p_value": 0.002,
      "avg_move_pct": 2.1,
      "sample_size": 47
    }
  ],
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": { "windows": [15, 60, 240, 1440] }
}

GET /v1/signals All

Multi-layer confluence detection across all active crises. Identifies which crises have multiple simultaneous risk signals — scenario confirmations, intensity spikes (from /v1/intensity), inbound cross-crisis connections (from /v1/connections), and humanitarian alerts. Higher confluence scores indicate more layers of risk converging.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/signals"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
data = requests.get(
    "https://polycrisis.world/api/v1/signals",
    headers=headers
).json()

for s in data["signals"]:
    print(f"{s['crisis_name']}: confluence {s['confluence_score']} ({s['layer_count']} layers)")

Response

json
{
  "signals": [
    {
      "crisis": "iran",
      "crisis_name": "Iran",
      "confluence_score": 4,
      "layers": [
        { "type": "scenarios", "count": 3 },
        { "type": "intensity", "score": 78 },
        { "type": "connections_inbound", "count": 2 },
        { "type": "humanitarian_alerts", "count": 1 }
      ],
      "layer_count": 4,
      "summary": "Iran showing confluence across all 4 risk layers..."
    }
  ],
  "generated_at": "2026-03-21T14:30:00Z",
  "meta": {
    "layers_checked": ["scenarios", "intensity", "connections_inbound", "humanitarian_alerts"],
    "min_layers": 2
  }
}

GET /v1/briefing All

Returns a cached intelligence briefing for a crisis theater. Two depth levels: light returns a 2-3 sentence summary updated every 30 minutes; deep returns a full analysis derived from the daily podcast transcript. No AI tokens consumed — briefings are pre-generated and cached.

Parameters

ParameterTypeRequiredDescription
crisis requiredstringYesCrisis theater to brief on.
depthstringNolight (2-3 sentences, 30-min cache) or deep (full analysis from daily briefing transcript, 1-hour cache). Default: light.

Request

curl
Python
curl
curl -H "Authorization: Bearer $POLYCRISIS_KEY" \
  "https://polycrisis.world/api/v1/briefing?crisis=iran&depth=deep"
python
import requests

headers = {"Authorization": "Bearer $POLYCRISIS_KEY"}
briefing = requests.get(
    "https://polycrisis.world/api/v1/briefing",
    headers=headers,
    params={"crisis": "iran", "depth": "deep"}
).json()

print(briefing["briefing"])

Response

json
{
  "crisis": "iran",
  "depth": "deep",
  "briefing": "**Iran (Intensity: 7.2, RISING):** IAEA confirmed 83.7% enrichment at Fordow, up from 60% baseline. Israeli defense minister statement interpreted as implicit strike authorization. CL=F up 1.4% on the development. Backchannel talks via Oman continue but no breakthrough indicators detected.",
  "event_count_48h": 37,
  "generated_at": "2026-03-21T10:15:00Z"
}

GET /v1/stream All

Server-Sent Events (SSE) endpoint for real-time streaming. Opens a persistent connection and pushes new events as they are processed. Supports filtering by crisis, event type, and minimum confidence.

Parameters

ParameterTypeRequiredDescription
crisisstringNoFilter stream to a specific crisis theater. Omit for all.
typestringNoFilter by event type (single value).
min_confidencenumberNoMinimum confidence score (0–1) for streamed events.

Event Types

EventDescription
new_eventA new crisis event was processed and added.
heartbeatKeepalive signal sent every 15 seconds.

Request

curl
Python
curl
curl -N -H "Authorization: Bearer $POLYCRISIS_KEY" \
  -H "Accept: text/event-stream" \
  "https://polycrisis.world/api/v1/stream?crisis=iran&type=nuclear"
python
import requests, json

headers = {
    "Authorization": "Bearer $POLYCRISIS_KEY",
    "Accept": "text/event-stream"
}
r = requests.get(
    "https://polycrisis.world/api/v1/stream",
    headers=headers,
    params={"crisis": "iran"},
    stream=True
)

for line in r.iter_lines(decode_unicode=True):
    if line.startswith("data: "):
        event = json.loads(line[6:])
        print(event.get("title", event))

Response Stream

sse
event: new_event
data: {"id":7824,"crisis":"iran","event_type":"nuclear","title":"IAEA confirms 83.7% enrichment at Fordow","lat":34.708,"lng":51.984}

event: heartbeat
data: {"ts":"2026-03-21T10:15:30Z"}

POST /v1/webhooks All

Register a webhook to receive real-time alerts. Events matching your filters are POSTed to your callback URL as they occur. The server returns an HMAC signing_secret when you create a webhook — use it to verify the X-Polycrisis-Signature header on inbound deliveries. Also supports GET (list webhooks) and DELETE (remove webhook).

Create Webhook — Body Parameters

ParameterTypeRequiredDescription
url requiredstringYesYour callback URL. Must be HTTPS.
triggersstring[]NoTrigger types to subscribe to: new_event, scenario_change, intensity_spike. Default: all.
crisisstringNoRestrict deliveries to this crisis theater.
event_typestringNoRestrict deliveries to this event type (applies to new_event).
min_confidencenumberNoSuppress events below this confidence (0–1).
intensity_thresholdnumberNoFire intensity_spike only when the index crosses this value.
filterstringNoFreeform label you can use server-side for your own routing.
cascade_alertbooleanNoAlso fire on cross-crisis connection effects.
cascade_theatersstring[]NoRestrict cascade alerts to the listed crisis theaters.

The response includes a signing_secret field — this is the only time the server returns it in cleartext. Store it securely and use it to HMAC-verify incoming webhook payloads.

Create Request

curl
Python
curl
curl -X POST -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-system.com/webhook",
    "triggers": ["new_event", "scenario_change"],
    "crisis": "iran",
    "event_type": "nuclear",
    "min_confidence": 0.6
  }' \
  https://polycrisis.world/api/v1/webhooks
python
import requests

headers = {
    "Authorization": "Bearer YOUR_KEY",
    "Content-Type": "application/json"
}
webhook = requests.post(
    "https://polycrisis.world/api/v1/webhooks",
    headers=headers,
    json={
        "url": "https://your-system.com/webhook",
        "triggers": ["new_event", "scenario_change"],
        "crisis": "iran",
        "event_type": "nuclear",
        "min_confidence": 0.6
    }
).json()

print(f"Webhook ID: {webhook['id']}")
print(f"Signing secret: {webhook['signing_secret']}")

Create Response

json
{
  "id": "wh_a9c3f1",
  "status": "active",
  "url": "https://your-system.com/webhook",
  "triggers": ["new_event", "scenario_change"],
  "crisis": "iran",
  "event_type": "nuclear",
  "min_confidence": 0.6,
  "intensity_threshold": null,
  "signing_secret": "whsec_cd3f9a...",
  "created_at": "2026-03-21T10:00:00Z"
}

Manage Webhooks

curl
# List all webhooks owned by this key
curl -H "Authorization: Bearer YOUR_KEY" \
  https://polycrisis.world/api/v1/webhooks

# Delete a webhook — ID goes in the JSON body, not the URL path
curl -X DELETE -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id": "wh_a9c3f1"}' \
  https://polycrisis.world/api/v1/webhooks

Use Cases

Practical examples for integrating POLYCRISIS data into trading systems, risk dashboards, and monitoring bots.

Quant Signal

Geopolitical Signal for Oil Trading

Monitor Iran scenario probabilities and correlate with oil futures. Generate trading signals when Hormuz disruption probability crosses your threshold.

python
import requests
import pandas as pd

API_KEY = "pk_YOUR_KEY"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Get Iran crisis intensity and Hormuz scenario probability
scenarios = requests.get(
    "https://polycrisis.world/api/v1/scenarios",
    headers=headers,
    params={"crisis": "iran"}
).json()

hormuz = next((s for s in scenarios["scenarios"]
    if "hormuz" in s["title"].lower()), None)
if hormuz:
    prob = hormuz["probability"]  # already 0-100
    print(f"Hormuz disruption probability: {prob}% [{hormuz['band']}]")
    if prob > 80:
        print("HIGH RISK -- consider oil long positions")

# Correlate with market data (Analyst+ plan required)
correlations = requests.get(
    "https://polycrisis.world/api/v1/correlations",
    headers=headers,
    params={"crisis": "iran", "market": "CL=F"}
).json()
print(f"Iran-Oil correlation: {correlations['correlations'][0]['correlation']}")
Monitoring

Crisis Event Monitoring Bot

Poll for new military events in real time. Alert your team when new high-confidence events appear in a crisis theater.

python
import requests
import time

API_KEY = "pk_YOUR_KEY"
headers = {"Authorization": f"Bearer {API_KEY}"}

seen_ids = set()
while True:
    events = requests.get(
        "https://polycrisis.world/api/v1/events",
        headers=headers,
        params={"crisis": "iran", "type": "military", "limit": 5}
    ).json().get("events", [])

    for event in events:
        if event["id"] not in seen_ids:
            seen_ids.add(event["id"])
            print(f"NEW: {event['title']} ({event.get('lat')}, {event.get('lng')})")

    time.sleep(300)  # Poll every 5 minutes
Risk

Multi-Crisis Risk Dashboard Data

Build a portfolio risk dashboard that pulls intensity scores across all crisis theaters and flags elevated risks.

python
import requests

API_KEY = "pk_YOUR_KEY"
headers = {"Authorization": f"Bearer {API_KEY}"}

crises = requests.get(
    "https://polycrisis.world/api/v1/crises",
    headers=headers
).json()

for crisis in crises["crises"]:
    data = requests.get(
        "https://polycrisis.world/api/v1/intensity",
        headers=headers,
        params={"crisis": crisis["id"]}
    ).json()
    current = data.get("current_index", {})
    print(f"{crisis['name']}: intensity {current.get('value')} [{current.get('band')}]")
Quant Signal

Scenario Backtesting Signal

Track scenario probability changes over time. When a scenario crosses a threshold, generate a trading signal for backtesting or live execution.

python
"""
Track scenario probability changes over time.
When a scenario crosses a threshold, generate a trading signal.
"""
import requests

API_KEY = "pk_YOUR_KEY"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Get scenario history for backtesting
history = requests.get(
    "https://polycrisis.world/api/scenario-history",
    params={"crisis": "iran"}
).json()

for scenario_id, entries in history.get("history", {}).items():
    if len(entries) < 2:
        continue
    latest = entries[-1]["prob"]
    previous = entries[-2]["prob"]
    delta = latest - previous
    if abs(delta) >= 10:
        direction = "UP" if delta > 0 else "DOWN"
        print(f"{direction} {scenario_id}: {previous}% -> {latest}% (delta {delta:+d})")