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.

bash
curl https://rugburn.io/api/risk-check/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

Response

json
{  "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.

bash
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:

typescript
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.