Skip to main content
The Risk Score is a number between 0.0 and 10.0 that summarizes how rug-pull-y a token looks based on on-chain evidence. It’s glass-box: the full list of signals that fired, with their weights and individual contributions, is in the API response. You can re-compute the score yourself.

Formula

The divisor 5000 is the calibration target — a raw contribution sum of 5,000 normalizes to 10.0. Real-world rug setups often reach raw sums of 20,000+; they all clip to 10.0.

Level bands

The level field bands the numeric score into four categories for UI:

Status

A partial_data score is a true lower bound — every signal in missing_signals[] is one that could have added to the score had its input been available.

A failed read is not missing data

missing_signals[] holds two different things: signals whose input does not exist yet, and signals whose read failed (a database error or timeout). The second kind is also listed in unavailable_signals[], which is always present: The risk block embedded in /tokens/{mint}/intel carries the same status, missing_signals and unavailable_signals. The seven holder-derived signals (single_holder_50pct, top10_high, top10_very_high, snipers_pct_high, insiders_pct_high, dev_held_high, dev_held_very_high) need a complete holder census of the mint. Until the mint has one, they sit in missing_signals[] rather than being evaluated over a partial holder set. That happens when the mint has never been censused, when the last census missed holders, or when it is too large to scan. A partial set would read a holder it never saw as holding 0%. If the check of the census itself fails, the seven are listed in unavailable_signals[] instead: retry.

Signals

Twelve signals across six categories. “Graded” signals scale their contribution with the magnitude of the underlying value (e.g. dev_held_high contributes more when the creator holds 30% vs 6%).

Holder concentration (graded)

LP + authority (boolean)

Sniper concentration (graded)

Insider concentration (graded)

Creator behavior (graded)

Metadata (boolean)

Total maximum raw contribution: 53,500 (every signal triggered at full strength).

Why this design

Glass-box so you can audit our judgment. If you disagree with a weight or threshold, you can subtract that signal’s contribution from the raw score and renormalize. The value field on each signal is the concrete measurement, not an opaque score — verifiable against the underlying on-chain data. Stacking thresholds (e.g. top10_high + top10_very_high) compound penalties for severe concentration without making any single threshold a cliff. Graded contribution keeps small differences in the underlying data from causing large score jumps. A token at 51% top-10 concentration doesn’t suddenly leap past one at 49%. Phase 0 strict precedence for dev_held_*: we only fire these when tokens.creator_source is populated. We never fall back to “largest holder is probably the creator” — that produced false positives in pre-Phase-0 testing on tokens where the largest holder was a CEX hot wallet or the AMM pool itself.

Re-computing the score

The response is glass-box on purpose. If you want to weight signals differently:
Or if you want a fully custom model: walk signals[*].value, ignore the weight/contribution, and feed the raw values into whatever you’d prefer.

See also

  • GET /tokens/{mint}/risk — the dedicated risk endpoint
  • GET /tokens/{mint}/intel — slim risk summary embedded in the dashboard payload
  • Quotas & errors — /risk is Free-tier rate-limited; no per-endpoint cap