Documentation

BTCFi Risk Layer API v1

Read-only JSON over HTTPS. Every response is derived from the latest scoring snapshot (methodology v1.0.0) and is refreshed on the indexer schedule. No authentication is required in v0.1; responses are cacheable for 60 seconds. All monetary values are USD, all scores are 0–100 where higher means lower risk.

Running the stack

npm install
npm run pipeline      # index Stacks data, then compute scores -> data/snapshot.json
npm run api           # http://localhost:4000  (file store, or PostgreSQL when DATABASE_URL is set)
npm run dashboard     # http://localhost:3000  (reads API_URL when set, else the committed snapshot)
GET

/v1/protocol-risk

Returns protocol risk metrics: the overall score and band, the four component scores with every factor, effective weights, current liquidity and the daily history for the requested window.

Query parameters
NameTypeDescription
protocolstringProtocol slug, e.g. zest. Omit for all tracked protocols.
window7d | 30d | 90dHistory window for tvl_history and score_history. Default 30d.
Example
curl https://api.btcfi.example/v1/protocol-risk?protocol=zest&window=7d

{
  "updated_at": "2026-09-18T06:25:31.000Z",
  "methodology_version": "1.0.0",
  "protocols": [{
    "protocol": "zest",
    "name": "Zest Protocol",
    "category": "Lending",
    "overall_score": 68,
    "band": "Moderate",
    "liquidity_score": 72.5,
    "activity_score": 16.3,
    "collateral_health": 93.9,
    "transparency_score": 93.7,
    "effective_weights": { "liquidity": 30, "activity": 25, "collateral": 25, "transparency": 20 },
    "liquidity_usd": 65385202,
    "borrowed_usd": 13581728,
    "utilization": 0.172,
    "components": [ { "key": "liquidity", "factors": [ ... ] }, ... ],
    "tvl_history": [ { "date": "2026-09-12", "tvlUsd": 64210044 }, ... ],
    "score_history": [ { "date": "2026-09-18", "overall": 68, ... } ]
  }]
}
GET

/v1/market-health

Returns ecosystem metrics across all tracked protocols: liquidity tracked with 7d / 30d change, active addresses, transactions, the average risk score, the band distribution and the 90-day ecosystem TVL series.

Example
curl https://api.btcfi.example/v1/market-health

{
  "protocols": 5,
  "liquidity_usd": 109789459,
  "liquidity_change_7d": 0.015,
  "active_addresses_7d": 223,
  "transactions_7d": 2830,
  "avg_risk_score": 63,
  "band_distribution": { "Low": 0, "Moderate": 3, "Elevated": 2, "High": 0 },
  "tvl_history": [ ... ]
}
GET

/v1/risk-alerts

Returns detected risk events such as liquidity movement, utilisation thresholds, activity swings and score changes. Each event carries a severity (info, watch, alert) and the measured delta.

Query parameters
NameTypeDescription
sinceISO 8601Only events at or after this timestamp.
kindstringliquidity | activity | collateral | transparency | score
Example
curl https://api.btcfi.example/v1/risk-alerts?since=2026-09-17T00:00:00Z

{
  "events": [
    { "slug": "zest", "ts": "2026-09-18T06:25:31.000Z", "kind": "activity", "severity": "watch",
      "message": "Zest Protocol transaction success rate 67% over 7 days", "delta": 0.667 }
  ]
}
GET

/v1/methodology

Returns the methodology version, the nominal component weights and the risk band thresholds, so integrators can label scores consistently.

Example
curl https://api.btcfi.example/v1/methodology

{
  "version": "1.0.0",
  "scale": "0-100, higher is safer",
  "weights": { "liquidity": 0.3, "activity": 0.25, "collateral": 0.25, "transparency": 0.2 },
  "bands": { "Low": "75-100", "Moderate": "60-74", "Elevated": "40-59", "High": "0-39" }
}

Data definitions

  • liquidity_usd — value locked on Stacks per DefiLlama, excluding borrowed value.
  • borrowed_usd / utilization — outstanding borrows and borrowed ÷ (liquidity + borrowed); lending protocols only.
  • tx_7d / unique_senders_7d — confirmed direct calls to the registered entry-point contracts in the last 7 days and the distinct sender principals; marked estimated when sampled.
  • score_delta_7d — overall score minus the score recorded 7 days earlier (null until history exists).
  • components[].factors[] — the exact inputs behind each component score: label, observed value, mapped 0–100 score and weight within the component.
  • effective_weights — the weights actually applied after redistributing non-applicable components.

Integration example

const res = await fetch(`${API}/v1/protocol-risk?protocol=stackingdao`);
const { protocols: [p] } = await res.json();

if (p.band === 'High' || p.band === 'Elevated') {
  showWarning(`${p.name}: risk score ${p.overall_score} (${p.band})`);
}

Source, methodology and the protocol registry live in the public repository. Contributions that add a protocol must cite public sources for every transparency field.