VisibleHand API Reference v0.3
Base URL: https://api.visiblehand.xyz  ·  MIT License Interactive Swagger ▸
Authentication
All read endpoints (GET) are public — no key required. Set X-API-Key header to bypass rate limits (contact for key).
Rate limit:  60 requests / minute per IP (default). 429 Too Many Requests is returned when exceeded. Headers: X-RateLimit-Limit, X-RateLimit-Remaining.
Endpoints
MethodPathDescription & Parameters
GET/risk/{code}Composite risk score + 95% CI + driver attributions + forecast
code: ISO-3166 alpha-2 (e.g. US, AR, UA)
→ RiskResponse · computed fresh or from cache
GET/risk/compareCompare up to 10 countries in one call
countries: comma-separated codes (e.g. US,BR,AR,DE)
→ list[RiskResponse]
GET/risk/{code}/historyAll stored score snapshots for a country
limit: int (default 100) · offset: int
→ list[HistoryPoint]
GET/risk/{code}/driversSigned per-indicator driver attributions
code: country code
→ list[DriverAttribution]
GET/risk/{code}/aspects5-aspect NLP breakdown (central-bank statement)
code: country code
→ AspectScoresResponse
GET/risk/{code}/forecast6-month and 12-month score extrapolations
code: country code
→ { '6m': ForecastPoint, '12m': ForecastPoint }
GET/risk/moversCountries with largest risk score change (7-day window)
limit: int (default 10)
→ list[MoverPoint]
GET/risk/bulkBatch score multiple countries (POST body)
body: { countries: [code, …] }
→ list[RiskResponse]
GET/indicators/{code}Raw economic indicator time series
code: country · metric: filter by name
→ list[IndicatorRow]
GET/events/{code}Political event feed with severity scores
code: country · limit: int
→ list[EventRow]
GET/governance/{code}Governance sub-scores (V-Dem, WJP, TI, FH)
code: country
→ GovernanceResponse
GET/nlp/{code}Central-bank NLP hawkishness + latest statement text
code: country
→ NLPResponse
GET/calibration/summaryMethodology, component weights, AUC estimate
→ CalibrationSummary
GET/calibration/rocFull ROC/PR curve data · include_curve=true for arrays
include_curve: bool
→ ROCResult
GET/calibration/datasetCrisis event dataset (220 events, 2000–2023)
→ { n_total, events: […] }
GET/healthAPI health + DB connectivity + scored country count
→ HealthResponse
GET/health/readyKubernetes readiness probe
→ 200 / 503
GET/metricsPrometheus scrape endpoint
→ text/plain
Example — GET /risk/{code}
Request
$ curl https://api.visiblehand.xyz/risk/AR # Optional weight overrides: $ curl "…/risk/AR?economic_weight=0.5 &political_weight=0.3 &nlp_weight=0.1 &governance_weight=0.1"
Parameters
ParamTypeDefault
economic_weightfloat0.45
political_weightfloat0.25
nlp_weightfloat0.20
governance_weightfloat0.10
Response — 200 OK
{ "country": "AR", "name": "Argentina", "composite": 84.3, "ci_low": 77.1, "ci_high": 91.2, "confidence":0.82, "risk_level":"Very High", "breakdown": { "economic": 88.1, "political": 71.0, "nlp_sentiment":85.0, "governance": 79.4 }, "top_drivers": [ "high_inflation", "high_debt_burden" ], "driver_attributions": [ {"name":"high_inflation", "contribution":18.2, "direction":"risk", "sub_scorer":"economic"} ], "forecast": { "6m": {"composite":87.0, "ci_low":79.0,"ci_high":95.0}, "12m":{"composite":90.1, "ci_low":78.0,"ci_high":100.0} }, "updated_at": "2026-06-27T14:30:00Z" }
Error Codes
StatusMeaningBody
200OKRequested resource
404Not Found{"detail":"…"} — unknown country code or no data yet
422Validation Error{"detail":[…]} — invalid parameter type/range
429Rate Limited{"error":"rate limit exceeded"}
500Server Error{"detail":"internal server error"}
SDK — Python Client
# Install pip install visiblehand # Sync from visiblehand import Client c = Client() score = c.risk("AR") print(score.composite, score.risk_level) # Async from visiblehand import AsyncClient async with AsyncClient() as c: scores = await c.compare(["US", "BR", "AR"])
SDK source: sdk/visiblehand/__init__.py · Install locally: pip install -e sdk/
VisibleHand v0.3 · MIT License · Free & open-source Interactive Swagger ▸