When to use this
The pre-trade endpoint is the right call when you need a YES/NO/MAYBE answer in tens of milliseconds. Internally it issues a single Supabase indexed read against our scan corpus, picks the most recent row, and returns a verdict plus the flags that matter for a buy decision.
If the mint has never been scanned, you get a clear verdict: "unknown" response with a link to trigger a scan. Trading routers should typically refuse to route unknowns (or queue a background scan + retry) rather than letting the user proceed blind.
GET /api/risk-check/[address]
Single-mint check. Returns within ~50ms when cache is warm.
curl https://rugburn.io/api/risk-check/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1vResponse
{ "address": "EPjFWdd...", "symbol": "USDC", "verdict": "ok", "score": 95, "confidence": 92, "flags": [], "freshness": "fresh", "scan_depth": "full", "scanned_at": "2026-05-25T14:00:00Z", "age_seconds": 124, "outcome": null, "latency_ms": 47, "rescan_url": "/scanner?address=...&autoScan=1", "details_url": "/tokens/..."}verdict — one of:
block— score < 30. Routers should refuse to swap or require explicit override.warn— score 30–59. Show risk to user before submitting.ok— score ≥ 60. Standard trade flow.unknown— no scan exists. Defer or queue a background scan.
freshness — how stale the cached row is:
fresh— < 5 minutes old. Edge-cached.stale— 5min–1h. Usable, but consider triggering a rescan in the background.cold— > 1h or missing. Caller should explicitly rescan before relying on it.
POST /api/risk-check/batch
Up to 50 mints in one round-trip. Designed for multi-hop trade pre-checks — for example a Jupiter route that touches 3 intermediate mints. Returns the same shape as the single endpoint, keyed by address.
curl -X POST https://rugburn.io/api/risk-check/batch \ -H "content-type: application/json" \ -d '{ "addresses": ["mint1", "mint2", "mint3"] }'Integrating with Vulcan / a trade router
The minimal pre-trade flow:
async function safeSwap(inputMint: string, outputMint: string, amount: bigint) { const res = await fetch(`https://rugburn.io/api/risk-check/${outputMint}`) const risk = await res.json() if (risk.verdict === "block") { throw new Error(`Refused: ${outputMint} (${risk.flags.join(", ")})`) } if (risk.verdict === "unknown" || risk.freshness === "cold") { // Queue a background scan, surface a warning, or block by policy return { status: "needs_scan", scan_url: risk.rescan_url } } // verdict === "warn" or "ok" — proceed, show flags to the user if warn return await router.executeSwap({ inputMint, outputMint, amount })}Adds ~50ms to the trade pipeline at p99, and saves the user from a meaningful share of rugs without requiring them to read the scan card themselves.
Limits + caching
- Single endpoint: edge-cached up to 60s, SWR 5min for fresh results.
- Batch endpoint: never cached. POSTs are always live reads.
- 50 addresses max per batch call.
- No auth required for read-only calls. Add an API key header to identify your traffic for ops support.