Live
Regime
Risk Score
Volatility
Model
fetching…

Overview

MacroPulse exposes a REST API that returns daily macro regime classifications, net Fed liquidity, PCA factor scores, and backtesting utilities. All responses are JSON.

Base URL

HTTPS · https://api.macropulse.live

Authentication

Authenticated endpoints require an X-MacroPulse-Key header. Obtain a key by registering below or at macropulse.live/#register.

bash
curl -H "X-MacroPulse-Key: mp_..." https://api.macropulse.live/v1/signals/latest

Rate Limits

Limits are enforced per API key, per rolling 24-hour window.

Plan Requests / day Historical data
Free 50 30 days
Starter 500 6 months (180 days)
Pro Unlimited Full
When you exceed your limit the API returns 429 Too Many Requests. The X-RateLimit-Reset header contains the UTC epoch when the window resets.

Error Codes

All errors return a JSON body with detail and code fields. HTTP status codes follow standard semantics.

StatusMeaning
401 Missing or invalid API key
403 Key revoked, plan tier insufficient for this endpoint, or key temporarily IP-locked — check the error field (ip_locked means retry after 15 min inactivity)
404 No data for requested date
422 Invalid parameters (see response body for field errors)
429 Rate limit exceeded
503 Data pipeline lag — daily ETL job in progress

GET /v1/signals/latest
GET Authenticated Primary

Returns the complete signal package for the most recent trading day. This is the primary endpoint — use this to get the current macro regime, liquidity signals, and PCA factors. All downstream strategies should start here.

Request Headers

HeaderRequiredDescription
X-MacroPulse-Key Yes Your API key (mp_...)

Python Example

python
import requests

resp = requests.get(
    "https://api.macropulse.live/v1/signals/latest",
    headers={"X-MacroPulse-Key": "mp_..."}
)
signal = resp.json()

# Regime-aware equity exposure
EXPOSURE = {
    "expansion":  1.00,
    "recovery":   0.75,
    "tightening": 0.25,
    "risk_off":   0.00,
}
weight = EXPOSURE[signal["regime"]["most_likely"]]

Response Schema

json
{
  "date": "2026-03-15",
  "regime": {
    "most_likely": "recovery",
    "probabilities": {
      "expansion":  0.08,
      "recovery":   0.72,
      "tightening": 0.15,
      "risk_off":   0.05
    },
    "confidence": "HIGH",
    "persistence_days": 14,
    "expected_duration_remaining_days": 8
  },
  "net_liquidity": {
    "level_bn": 5842.3,
    "change_4w_bn": -124.5,
    "zscore": -1.1,
    "trend": "CONTRACTING"
  },
  "pca_factors": {
    "pc1": 0.82,
    "pc2": -0.34,
    "pc3": 0.11,
    "pc4": -0.05,
    "variance_explained_pct": [0.42, 0.22, 0.14, 0.09]
  },
  "model_metadata": {
    "pca_fit_date": "2026-01-15",
    "hmm_fit_date": "2026-01-15",
    "data_vintage": "2026-03-15T18:31:22Z"
  }
}

Regime Field Descriptions

FieldTypeDescription
most_likely string Dominant regime: expansion, recovery, tightening, risk_off
probabilities object Posterior probability for each state. Values sum to 1.0
confidence string HIGH (≥70%), MODERATE (≥50%), LOW (<50%)
persistence_days int Consecutive days the model has held the current regime
expected_duration_remaining_days int HMM-derived forward estimate of days remaining in this regime

GET /v1/signals/{date}
GET Authenticated

Retrieve the complete signal package for a specific historical date. Returns 404 if no data exists for the requested date (weekends, holidays, or dates before the data start).

Path Parameters

ParameterTypeDescription
date string ISO 8601 date in YYYY-MM-DD format

Example

bash
curl -H "X-MacroPulse-Key: mp_..." \
  https://api.macropulse.live/v1/signals/2025-10-01

Response schema is identical to GET /v1/signals/latest.


GET /v1/signals/range
GET Authenticated

Returns a time-series array of signal packages for a date range. Useful for backtesting and portfolio research. Maximum window: 365 calendar days.

Query Parameters

ParameterRequiredDescription
start Yes Start date, ISO format YYYY-MM-DD
end Yes End date, ISO format YYYY-MM-DD

Python Example — Backtest Workflow

python
import requests, pandas as pd

resp = requests.get(
    "https://api.macropulse.live/v1/signals/range",
    params={"start": "2025-01-01", "end": "2025-12-31"},
    headers={"X-MacroPulse-Key": "mp_..."}
)
signals = pd.DataFrame(resp.json())
signals["regime"] = signals["regime"].apply(lambda x: x["most_likely"])

GET /v1/regime/current
GET Public

Returns the most recent regime classification. No API key required — suitable for public dashboards, widgets, and open integrations.

Example

bash
curl https://api.macropulse.live/v1/regime/current

Response

json
{
  "timestamp": "2026-03-15T00:00:00",
  "macro_regime": "recovery",
  "risk_score": 22.5,
  "probabilities": {
    "expansion":  0.08,
    "recovery":   0.72,
    "tightening": 0.15,
    "risk_off":   0.05
  },
  "volatility_state": "normal",
  "model_version": "v2"
}

GET /v1/regime/history
GET Public

Returns a paginated list of historical regime rows in reverse-chronological order. Useful for charting regime timelines without authentication.

Query Parameters

ParameterDefaultDescription
limit 90 Number of rows to return. Maximum 1000
start ISO date filter — restrict results on or after this date
end ISO date filter — restrict results on or before this date

Python Example

python
import requests, pandas as pd

history = requests.get(
    "https://api.macropulse.live/v1/regime/history",
    params={"limit": 365}
).json()
df = pd.DataFrame(history)

GET /v1/liquidity
GET Public

Returns net Fed liquidity time-series. Net liquidity is computed as Fed Assets − RRPO − TGA in billions of USD, with daily changes and z-scores.

Query Parameters

ParameterDefaultMax
limit 30 500

Example

bash
curl "https://api.macropulse.live/v1/liquidity?limit=90"

GET /v1/scorecard
GET Public

Returns 5 normalized macro signal gauges in the range [-1.0, +1.0]. Each gauge is the 20-day momentum of a key macro indicator, standardized by historical volatility.

Response

json
{
  "growth_momentum":    0.42,
  "inflation_momentum": -0.18,
  "liquidity":          -0.65,
  "financial_stress":   0.31,
  "dollar_strength":    0.12,
  "computed_at":        "2026-03-15T18:31:22.401Z"
}

Signal Definitions

SignalPositive (+1)Negative (−1)Source indicator
growth_momentum Yield curve steepening Flattening / inversion d_yield_curve 20d momentum
inflation_momentum Rising 10Y yields Falling 10Y yields d_10y 20d momentum
liquidity High net Fed liquidity Liquidity drain net_liquidity z-score
financial_stress Calm markets Stress / widening spreads -(d_hy + d_vix) momentum
dollar_strength Strong USD Weak USD d_dxy 20d momentum

POST /v1/backtest
POST Pro

Run a historical regime replay over a specified date range. Returns aggregate statistics about regime distribution, persistence, and risk score trajectory. Useful for strategy validation before live deployment.

Request Body

json
{
  "start": "2024-01-01",
  "end":   "2025-01-01"
}

Python Example

python
resp = requests.post(
    "https://api.macropulse.live/v1/backtest",
    json={"start": "2024-01-01", "end": "2025-01-01"},
    headers={"X-MacroPulse-Key": "mp_..."}
)
bt = resp.json()
print(bt["summary"]["avg_persistence_days"])  # e.g. 18.4

Response Summary Fields

FieldDescription
total_days Trading days included in the backtest range
transitions Number of regime-change events detected
avg_persistence_days Mean number of consecutive days per regime episode
mean_risk_score Average signed risk score over the full period
regime_distribution Percentage of trading days in each regime state

GET /v1/performance
GET Authenticated

Returns performance attribution comparing a regime-filtered strategy against a buy-and-hold benchmark. All metrics are computed using daily SPY returns as the base instrument.

Response Includes

FieldDescription
sharpeAnnualized Sharpe ratio for the regime-filtered strategy
max_drawdownMaximum peak-to-trough drawdown (negative float)
total_returnCumulative return over the full period
alphaAnnualized alpha versus buy-and-hold benchmark
by_regimePer-regime breakdown of returns and hit rate

GET /v1/forecast
GET Paid

Returns an ARIMA(1,0,1)-based forward projection of macro regime probabilities for up to 10 business days. A separate ARIMA model is fit on each probability column and on the risk score. Probabilities are clipped to [0,1] and renormalised to sum to 1. The confidence field reflects concentration across the forecast — a highly concentrated regime yields higher confidence. Requires Starter or Pro tier.

Query Parameters

horizonintegerBusiness days to forecast. Range: 1–10. Default: 5.

Response

json
{
  "horizon": 5,
  "generated_at": "2026-04-14T09:00:00+00:00",
  "forecast": [
    {
      "date": "2026-04-15",
      "regime": "recovery",
      "confidence": 0.72,
      "risk_score": 1.1,
      "prob_expansion": 0.11,
      "prob_recovery": 0.71,
      "prob_tightening": 0.13,
      "prob_risk_off": 0.05
    }
  ]
}
GET /v1/signals/history
GET API Key

Returns a compact regime history — date, regime label, risk score, and all four probability columns. Available to all authenticated tiers. The window is capped by plan: Free 30 days   Starter 180 days   Pro 365 days. Useful for building charts, regime calendars, and transition analysis.

Query Parameters

daysintegerNumber of days of history. Default: 90. Max: 365 (server clamps to your tier limit — Free 30, Starter 180, Pro 365).

Response

json
[
  {
    "date": "2026-04-14",
    "regime": "recovery",
    "risk_score": 1.24,
    "prob_expansion": 0.12,
    "prob_recovery": 0.71,
    "prob_tightening": 0.11,
    "prob_risk_off": 0.06
  }
]
GET /v1/account
GET API Key

Returns account metadata for the authenticated API key — tier, product line, usage, entitlements, and billing portal link. Works with any valid key including Free tier. Use billing_portal_url to redirect the user to Stripe Customer Portal for subscription management.

Response

json
{
  "tier": "pro",
  "tier_label": "Pro",
  "product": "macropulse",
  "product_line": "macropulse",
  "agent_count": 1,
  "payment_status": "active",
  "features": ["signals", "liquidity", "scorecard", "forecast", "backtest", "webhook", "commentary"],
  "usage": {
    "today_requests": 14,
    "daily_limit": 5000
  },
  "billing_portal_url": "https://api.macropulse.live/v1/billing/stripe/portal",
  "docs_url": "https://macropulse.live/api-docs.html"
}
GET /v1/public/regime
GET Public

Returns the current macro regime with an equity exposure recommendation and a plain-English interpretation. No API key required. Designed as the free-tier entry point — enough signal to be useful, with a link to upgrade for the full package (scorecard, forecast, webhook alerts, factor decomposition).

Response

json
{
  "date": "2026-04-14",
  "regime": "recovery",
  "regime_label": "Recovery",
  "emoji": "🔵",
  "risk_score": 1.2,
  "equity_exposure": "75%",
  "interpretation": "Liquidity re-injecting after stress. Risk appetite healing but not fully restored. Positive bias with elevated caution.",
  "upgrade": {
    "message": "Get the full signal package — scorecard, 5-day forecast, webhook alerts, and factor decomposition.",
    "url": "https://macropulse.live/#pricing"
  }
}
GET /v1/public/chart-data
GET Public

Last 730 days of regime history for interactive charts and performance analysis — no API key required. Each row includes cumulative returns for a regime-weighted strategy, S&P 500 buy-and-hold, and gold. The stats field includes Sharpe proxy, max drawdown, annualised return, and regime distribution.

Response

json
{
  "days": 730,
  "generated_at": "2026-04-14T09:00:00Z",
  "series": [
    {
      "date": "2024-04-14",
      "regime": "recovery",
      "risk_score": 0.82,
      "sp500": 100.0,
      "gold": 100.0,
      "strategy": 100.0
    }
  ],
  "stats": {
    "sharpe_proxy": 1.42,
    "max_drawdown": -8.3,
    "avg_persistence_days": 47.2,
    "strategy_annual_return": 18.4,
    "bh_annual_return": 14.1,
    "total_days": 730,
    "regime_distribution": {
      "expansion": 0.28,
      "recovery": 0.41,
      "risk_off": 0.07,
      "tightening": 0.24
    }
  }
}
GET /v1/irl/heartbeat
GET IRL Key

Issues a fresh signed heartbeat for use in /irl/authorize requests when LAYER2_ENABLED=true on the IRL Engine. Requires an IRL-tier API key (irl_sidecar, irl_audit, or owner). Each call returns a new heartbeat with a strictly increasing sequence_id — do not reuse. The heartbeat signature is Ed25519 over a canonical JSON blob of the heartbeat fields.

Response

json
{
  "sequence_id": 1042,
  "timestamp_ms": 1744624800000,
  "regime_id": 2,
  "mta_ref": "a3f7c2...",
  "signature": "ed25519:b5e3a1..."
}
Fetch a new heartbeat immediately before each /irl/authorize call. The IRL Engine rejects heartbeats older than its configured replay window (default: 30 seconds).
GET /v1/irl/audit
GET IRL Audit (L2)

Deep decomposition of the current macro regime signal. Available exclusively to irl_audit-tier keys (IRL Engine Audit — L2 licence, minimum 3 agents). Returns PCA factor attribution, stress indicator z-scores vs 90-day window, liquidity attribution in $bn, HMM transition probability matrix for the current regime, and model drift health flags.

Response

json
{
  "generated_at": "2026-04-14T09:00:00+00:00",
  "date": "2026-04-14",
  "regime": "recovery",
  "risk_score": 1.24,
  "agent_count": 3,
  "factor_attribution": [
    { "factor": "PC1", "description": "Liquidity & rates — primary driver of risk-on/risk-off",
      "value": 0.612, "direction": "bullish" },
    { "factor": "PC2", "description": "Risk appetite — equity momentum vs credit stress",
      "value": -0.09, "direction": "neutral" },
    { "factor": "PC3", "description": "Credit stress — HY spreads vs investment grade",
      "value": -0.22, "direction": "bearish" },
    { "factor": "PC4", "description": "Dollar & momentum — DXY and cross-asset momentum",
      "value": 0.18, "direction": "bullish" }
  ],
  "stress_indicators": [
    { "name": "VIX (equity vol)", "value": -0.0812, "z_score": -0.84, "flag": "normal" },
    { "name": "HY credit spread", "value": 0.0031, "z_score": 0.42, "flag": "normal" },
    { "name": "Yield curve (10Y-2Y)", "value": 0.0041, "z_score": 1.21, "flag": "normal" },
    { "name": "DXY (dollar index)", "value": -0.0019, "z_score": -0.61, "flag": "normal" },
    { "name": "Net Fed liquidity", "value": 5823100.0, "z_score": 0.33, "flag": "normal" }
  ],
  "liquidity": {
    "trend": "expanding",
    "latest_bn_usd": 5823.1,
    "30d_change_bn_usd": 142.6
  },
  "transition_risk": {
    "expansion": 0.1042,
    "recovery": 0.7831,
    "tightening": 0.0882,
    "risk_off": 0.0245
  },
  "model_health": {
    "status": "healthy",
    "flags": [],
    "pca_explained_variance": 0.0021,
    "regime_persistence": 0.8314,
    "feature_mean_shift": 0.0084
  }
}

Authentication Endpoints

POST /v1/auth/register
POST Public

Step 1 of 2: submit your email to receive a 6-digit verification code. Registration is a two-step flow to ensure only real email addresses receive API keys.

Request Body

json
{ "email": "you@example.com" }

Response (202 Accepted)

json
{
  "status": "verification_sent",
  "email": "you@example.com"
}
A 6-digit code valid for 15 minutes is emailed to you. Pass it to POST /v1/auth/verify to complete registration and receive your API key.
POST /v1/auth/verify
POST Public

Step 2 of 2: submit the verification code from your email to create your account and receive your API key.

Request Body

json
{ "email": "you@example.com", "code": "483921" }

Response (201 Created)

json
{
  "api_key":     "mp_...",
  "email":       "you@example.com",
  "tier":        "free",
  "daily_limit": 50
}
The api_key value is shown once. Copy and store it securely — it cannot be retrieved again. Use POST /v1/auth/rotate if you lose access.
POST /v1/auth/rotate
POST Authenticated

Rotate your API key. The current key is immediately revoked and a new one is returned. Update any applications before calling this endpoint.

Request Headers

HeaderRequiredDescription
X-MacroPulse-Key Yes Your current API key. It will be invalidated upon success.

Example

bash
curl -X POST \
  -H "X-MacroPulse-Key: mp_old_key" \
  https://api.macropulse.live/v1/auth/rotate
The old key stops working immediately. Ensure all production integrations are updated before rotating.