DeFi lending protocols hold billions in TVL. When crypto markets shift from bullish to bearish in minutes, protocols need automated triggers to protect depositors — lowering LTV ratios, pausing new borrows, or increasing liquidation buffers.
Most protocols rely on price oracles alone. But price is a lagging indicator. By the time BTC drops 10%, the damage is done.
Vigil detects regime shifts before they hit price. Our dual-layer ML ensemble analyzes 77+ features (momentum, microstructure, order flow, sentiment, prediction markets) and classifies the market into regimes with 65.5% accuracy on high-volatility conditions — the exact moments when protection matters most.
Your Protocol Vigil API
───────────── ─────────
Poll every 5 min ──────────────────► GET /v1/risk-score
│
◄──────────────────── { "market_risk": 0.92,
"verdict": "STAY_OUT",
"protection_active": true,
"layers_triggered": ["crash_protection"] }
If risk > threshold ──► Trigger on-chain action
• Lower LTV from 80% → 60%
• Pause new borrows
• Increase liquidation buffer
• Alert governance multisig
curl -X POST https://api.vigilsignals.com/api/v1/register \
-H "Content-Type: application/json" \
-d '{"name": "Your Protocol", "email": "dev@yourprotocol.xyz"}'
Response:
{
"client_id": "vig_cl_abc123...",
"client_secret": "vig_sk_def456...",
"tier": "free",
"message": "Store your client_secret securely."
}
curl -X POST https://api.vigilsignals.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "vig_cl_abc123...",
"client_secret": "vig_sk_def456..."
}'
Response:
{
"access_token": "eyJhbG...",
"token_type": "bearer",
"expires_in": 3600
}
curl -H "Authorization: Bearer eyJhbG..." \
https://api.vigilsignals.com/v1/risk-score
Response:
{
"market_risk": 0.68,
"regime": "mid_vol",
"verdict": "CAUTIOUS",
"protection_active": true,
"layers_triggered": ["ml_confidence_gate", "btc_first_altcoin_gate"],
"timestamp": "2026-05-14T18:00:00Z"
}
"""Vigil risk monitor for DeFi protocols."""
import time
import requests
VIGIL_CLIENT_ID = "vig_cl_..."
VIGIL_CLIENT_SECRET = "vig_sk_..."
VIGIL_API = "https://api.vigilsignals.com"
# Risk thresholds for your protocol
RISK_THRESHOLD_CAUTION = 0.65 # Lower LTV
RISK_THRESHOLD_CRITICAL = 0.85 # Pause borrows
def get_token() -> str:
"""Get a fresh API token (cache for 55 min)."""
resp = requests.post(f"{VIGIL_API}/oauth/token", json={
"grant_type": "client_credentials",
"client_id": VIGIL_CLIENT_ID,
"client_secret": VIGIL_CLIENT_SECRET,
})
resp.raise_for_status()
return resp.json()["access_token"]
def get_risk_score(token: str) -> dict:
"""Poll current market risk."""
resp = requests.get(
f"{VIGIL_API}/v1/risk-score",
headers={"Authorization": f"Bearer {token}"},
)
resp.raise_for_status()
return resp.json()
def handle_risk(risk_data: dict):
"""React to risk level changes."""
risk = risk_data["market_risk"]
verdict = risk_data["verdict"]
layers = risk_data["layers_triggered"]
if risk >= RISK_THRESHOLD_CRITICAL:
# CRITICAL: Pause new borrows, alert governance
print(f"🚨 CRITICAL RISK: {risk:.2f} — {verdict}")
print(f" Protection layers: {layers}")
# trigger_pause_borrows()
# alert_governance_multisig()
# increase_liquidation_buffer(1.5)
elif risk >= RISK_THRESHOLD_CAUTION:
# CAUTION: Lower LTV ratios
print(f"⚠️ ELEVATED RISK: {risk:.2f} — {verdict}")
# lower_ltv_ratio(0.60)
# increase_reserve_factor(0.20)
else:
# NORMAL: Standard parameters
print(f"✅ NORMAL: {risk:.2f} — {verdict}")
# Main loop — poll every 5 minutes
token = get_token()
token_expires = time.time() + 3300 # Refresh at 55 min
while True:
# Refresh token if needed
if time.time() > token_expires:
token = get_token()
token_expires = time.time() + 3300
risk_data = get_risk_score(token)
handle_risk(risk_data)
time.sleep(300) # 5 minutes
const VIGIL_API = "https://api.vigilsignals.com";
async function getToken(clientId, clientSecret) {
const resp = await fetch(`${VIGIL_API}/oauth/token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
}),
});
const data = await resp.json();
return data.access_token;
}
async function getRiskScore(token) {
const resp = await fetch(`${VIGIL_API}/v1/risk-score`, {
headers: { Authorization: `Bearer ${token}` },
});
return resp.json();
}
// Usage
const token = await getToken("vig_cl_...", "vig_sk_...");
const risk = await getRiskScore(token);
if (risk.market_risk >= 0.85) {
// Trigger emergency protocol actions
console.log("🚨 Critical risk detected:", risk.verdict);
}
For protocols that need instant reaction (not 5-minute polling), the WebSocket stream pushes regime changes the moment they're detected:
import asyncio
import websockets
import json
VIGIL_WS = "wss://api.vigilsignals.com/v1/stream"
async def listen_regime_changes(token: str):
"""Connect to Vigil WebSocket for real-time regime alerts."""
async with websockets.connect(f"{VIGIL_WS}?token={token}") as ws:
async for message in ws:
data = json.loads(message)
if data.get("type") == "heartbeat":
continue
if data["event_type"] == "regime_change":
regime = data["data"]
risk = regime.get("ensemble_prob_down", 0)
if risk >= 0.85:
# Immediate on-chain action
trigger_emergency_protocol(regime)
asyncio.run(listen_regime_changes("eyJhbG..."))
| market_risk | verdict | Recommended Action |
|---|---|---|
| 0.0 – 0.30 | BULLISH | Normal parameters, full LTV |
| 0.30 – 0.45 | NEUTRAL | Standard operations |
| 0.45 – 0.65 | CAUTIOUS | Consider lowering LTV 5-10% |
| 0.65 – 0.85 | CAUTIOUS | Lower LTV to 60%, increase reserves |
| 0.85 – 1.0 | STAY_OUT | Pause new borrows, alert governance |
The layers_triggered array in the risk-score response tells you exactly which safety mechanisms are active. This isn't marketing — it's architecture. Each layer operates independently:
| Layer | Name | Trigger Condition | What It Does |
|---|---|---|---|
| 1 | ML Confidence Gate | prob_down > 0.58 + confidence > 0.10 |
Blocks all new entries when the ensemble is bearish with meaningful confidence |
| 2 | BTC-First Altcoin Gate | BTC prob_down > 0.58 OR (BTC dominance > 60% + bearish) |
Pauses all altcoin signals — alts follow BTC down |
| 3 | Signal Quality Filter | signal_strength < 0.5 |
Filters out weak/noisy signals that don't meet minimum conviction |
| 4 | Best Signal Only | Multiple candidates in same bucket | Only the single strongest signal executes — quality over quantity |
| 5 | Crash Protection | All 4 Layer-1 models agree + price >5% below 200-SMA | Emergency override — pauses everything during structural crashes (like 2022) |
Why this matters for DeFi: When layers_triggered contains "crash_protection", it means 4 independent ML models (XGBoost, LSTM, Random Forest, Transformer) all agree the market is in genuine danger AND price confirms a structural breakdown. This is the highest-confidence danger signal Vigil produces — the exact moment a lending protocol should pause borrows.
Layer independence: Each layer can trigger independently. You might see ["ml_confidence_gate", "btc_first_altcoin_gate"] during a normal bearish period (models are cautious but no crash), or ["crash_protection"] during a genuine market meltdown. The more layers active, the more dangerous the conditions.
| Feature | Price Oracles | Vigil |
|---|---|---|
| Detection speed | Reactive (after price moves) | Predictive (before price moves) |
| Data sources | 1 (price) | 77+ features (momentum, sentiment, on-chain, order flow) |
| Regime awareness | None | Low/mid/high volatility classification |
| Accuracy on high-vol | N/A | 65.5% on unseen data (AUC 0.689) |
| Bear market protection | None | 0% loss vs -73% buy-and-hold in 2022 |
| Tier | Rate Limit | Latency | Best For |
|---|---|---|---|
| Free | 50/day | 60 min delay | Evaluation & testing |
| Starter ($500/mo) | 1K/day | 15 min delay | Dashboard integrations |
| Pro ($2K/mo) | 10K/day | Real-time + WebSocket | Production trading systems |
| Enterprise ($10K+/mo) | Unlimited | Real-time + SLA | Critical infrastructure |
Once you've tested with the Free tier and are ready for production access, upgrade via the API:
import requests
TOKEN = "your_access_token"
# Get a Stripe checkout URL for the Pro tier
resp = requests.post(
"https://api.vigilsignals.com/api/v1/billing/checkout",
params={"tier": "pro"},
headers={"Authorization": f"Bearer {TOKEN}"},
)
checkout_url = resp.json()["checkout_url"]
print(f"Complete payment at: {checkout_url}")
# Open this URL in a browser to complete Stripe checkout
# Or via curl:
curl -X POST "https://api.vigilsignals.com/api/v1/billing/checkout?tier=starter" \
-H "Authorization: Bearer YOUR_TOKEN"
Available tiers: starter ($500/mo) or pro ($2,000/mo). Enterprise requires custom invoicing — contact hello@vigilsignals.com.
After payment completes, your rate limits upgrade immediately (no restart needed). Manage your subscription anytime:
curl -X POST "https://api.vigilsignals.com/api/v1/billing/portal" \
-H "Authorization: Bearer YOUR_TOKEN"
Questions? Contact us at hello@vigilsignals.com