Quickstart
Get an API key, install the Python SDK, run your first portfolio analysis — all under 60 seconds.
Get Your API Key
Sign up and generate your API key — takes under a minute. No password needed.
API keys look like rm_user_* or rm_agent_*
There is no separate public demo secret — older rm_demo_* strings are not valid Bearer credentials. Try the public MAG7 list: curl "https://riskmodels.app/api/tickers?mag7=true"
For metrics, balance, and the examples below, create a key on Get key.
Install the SDK
The Python SDK handles ticker resolution, semantic field names, validation, and LLM context formatting. Install with the xarray extra for multi-dimensional portfolio math.
Raw REST (Python)
pip install requests pandas pyarrowTypeScript / Node.js
npm install node-fetch # or use native fetch in Node 18+Colab: full quickstart notebook
Step-by-step Python examples: hedge ratios, L3 decomposition, precision hedge charts, Deep Dive (DD) snapshots (GET /api/snapshot/<ticker>), long history and EAV pulls with optional response lineage (_metadata), /api/data/security-history, and notes on offline company context in DD renders.
Make Your First Request
Analyze portfolios or fetch risk metrics for any ticker (e.g., NVDA, AAPL, MSFT). The SDK auto-normalizes ticker aliases and wire field names.
Python SDK (Recommended)
Four common patterns — each uses riskmodels-py instead of hand-rolling REST, ticker cleanup, and field renaming.
1 — Hedge a single stock (alias resolution)
from riskmodels import RiskModelsClient
client = RiskModelsClient.from_env() # RISKMODELS_API_KEY from environment
# as_dataframe=True attaches metadata (ERM3 legend, semantic cheatsheet)
df = client.get_metrics("NVDA", as_dataframe=True)
print(f"Market Hedge Ratio: {df['l3_market_hr'].iloc[0]:.2f}")
print(f"Residual Risk (Idiosyncratic): {df['l3_residual_er'].iloc[0]:.1%}")2 — Analyze a weighted portfolio
from riskmodels import RiskModelsClient
client = RiskModelsClient.from_env()
portfolio = {
"AAPL": 0.4,
"MSFT": 0.3,
"NVDA": 0.2,
"GOOGL": 0.1,
}
# analyze is an alias for analyze_portfolio; GOOGL may resolve to GOOG
pa = client.analyze(portfolio)
print("Portfolio-Level L3 Hedge Ratios:")
for key, val in pa.portfolio_hedge_ratios.items():
v = f"{val:.4f}" if val is not None else "n/a"
print(f"{key}: {v}")3 — Build a multi-dimensional factor cube
from riskmodels import RiskModelsClient
# pip install riskmodels-py[xarray] — builds Ticker × Date × Metric cube
client = RiskModelsClient.from_env()
ds = client.get_dataset(["AAPL", "TSLA", "META"], years=2)
meta_sector_hr = ds.sel(ticker="META")["l3_sector_hr"]
meta_sector_hr.plot()Requires the [xarray] extra (see Install the SDK).
4 — Generate LLM-ready context
from riskmodels import RiskModelsClient, to_llm_context
client = RiskModelsClient.from_env()
pa = client.analyze({"NVDA": 0.5, "AMD": 0.5})
# Markdown tables, lineage, ERM3 legend — ready for LLM prompts
print(to_llm_context(pa))| Feature | Raw requests (example scripts) | RiskModels SDK |
|---|---|---|
| Ticker cleanup | Manual ticker.upper() | Automatic (e.g. GOOGL → GOOG) |
| Field names | Wire keys (l3_res_er, l3_mkt_hr) | Semantic names (l3_residual_er, l3_market_hr) |
| Validation | None | Warns on ER sum / HR sign issues (configurable) |
| Context for agents | Raw JSON | Markdown tables + ERM3 legend via to_llm_context |
Production auth: set RISKMODELS_CLIENT_ID and RISKMODELS_CLIENT_SECRET, then RiskModelsClient.from_env() — the SDK refreshes OAuth2 client-credentials tokens. Full flow: Authentication guide.
The SDK emits ValidationWarning for ticker aliases (GOOGL→GOOG) and returns semantic column names (l3_market_hr instead of raw l3_mkt_hr). See Agent-Native Helpers for all SDK features.
Raw REST (Python)
import requests
API_KEY = "rm_agent_live_..."
BASE_URL = "https://riskmodels.app/api"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Get latest metrics for NVDA (V3: fields nest under "metrics")
resp = requests.get(f"{BASE_URL}/metrics/NVDA", headers=HEADERS)
body = resp.json()
m = body["metrics"] # Wire keys (l3_mkt_hr) need manual remap
print(f"Residual Risk: {(m.get('l3_res_er') or 0):.1%}")
print(f"Market Hedge: {(m.get('l3_mkt_hr') or 0):.2f}")
print(f"Vol (23d): {(m.get('vol_23d') or 0):.1%}")
# Note: No ticker alias detection, no semantic normalization, no validationRaw REST requires manual parsing of nested body["metrics"] objects, no ticker alias detection, and OAuth token rotation logic for production use. The SDK handles all of this.
TypeScript
const API_KEY = "rm_agent_live_...";
const BASE_URL = "https://riskmodels.app/api";
const resp = await fetch(`${BASE_URL}/metrics/NVDA`, {
headers: { Authorization: `Bearer ${API_KEY}` }
});
const body = await resp.json();
const m = body.metrics;
console.log(`Residual Risk: ${((m.l3_res_er ?? 0) * 100).toFixed(1)}%`);
console.log(`Market Hedge: ${(m.l3_mkt_hr ?? 0).toFixed(2)}`);
console.log(`Vol (23d): ${((m.vol_23d ?? 0) * 100).toFixed(1)}%`);cURL
curl -X GET "https://riskmodels.app/api/metrics/NVDA" \
-H "Authorization: Bearer rm_agent_live_..."Parquet export (ticker returns)
Tabular responses omit _metadata in the file body — use X-Risk-Model-Version, X-Data-As-Of, and related headers on the HTTP response. See Response metadata.
# Bulk history as Parquet (no JSON _metadata in file — use X-Risk-* headers)
curl -sG "https://riskmodels.app/api/ticker-returns" \
--data-urlencode "ticker=NVDA" \
--data-urlencode "format=parquet" \
-H "Authorization: Bearer rm_agent_live_..." \
-o nvda_returns.parquet
# Equivalent: Accept header instead of format=
curl -sG "https://riskmodels.app/api/ticker-returns?ticker=NVDA" \
-H "Authorization: Bearer rm_agent_live_..." \
-H "Accept: application/vnd.apache.parquet" \
-o nvda_returns.parquetTry the CLI (`riskmodels-cli`)
BetaGlobal install gives you riskmodels: config, billed SQL query, balance, and manifest for agents. Portfolio decomposition and drift monitoring are available via the REST API and Python SDK; CLI agent commands are placeholders.
Install CLI
npm install -g riskmodels-cliCLI Commands
# riskmodels-cli — install: npm install -g riskmodels-cli
# API key (billed mode; default base URL https://riskmodels.app)
riskmodels config set apiKey rm_agent_live_...
# Read-only SQL against your account (see /api/cli/query)
riskmodels query "SELECT ticker, company_name FROM ticker_metadata LIMIT 5"
# Account balance
riskmodels balance
# Static tool manifest for agents (no auth)
riskmodels manifest --format anthropic
# Portfolio automation: use REST POST /api/batch/analyze, Python SDK, or MCP discovery + HTTP — not via agent subcommands yet
riskmodels agent decompose --help # placeholder; see CLI READMEConfiguration
# CLI stores settings in ~/.config/riskmodels/config.json
# Example keys (use "riskmodels config init" or "riskmodels config set"):
#
# Billed mode:
# apiKey — rm_agent_* key
# apiBaseUrl — https://riskmodels.app (optional)
#
# Direct Supabase dev mode:
# supabaseUrl, serviceRoleKey — see archive/CLI_COMMAND_TESTING.mdCLI commands shipped today: config, query, schema (direct mode), balance, manifest, agent (stubs). For full portfolio flows use API docs or riskmodels-py.
Explore more
Now that you have your first request working, explore the full API capabilities.