Risk-aware search
The judgment pipeline behind /v2/search and /v2/resolve — policies, gate overrides, and the reasons, warnings and suppressedBy codes that explain every result.
GET /v2/search and GET /v2/resolve share one pipeline. This page explains how it judges; the
routes are on Search & Resolve.
The judgment pipeline
Candidates come from three sources, merged and deduped by mint: a live market-data provider for long-tail coverage, the token index, and the curated asset registry. Each candidate then passes through four stages:
- Intent classification — is the query a mint address, a ticker or a name?
(
interpretation.intent). A mint address is a lookup, never fuzzy. - Hard gates — a policy decides which candidates are suppressed. Suppressed rows are
returned under
suppressed[]with the gate that fired; nothing is silently hidden. - Weighted score — the survivors are ranked (
score.total,score.components). - Explanations — every ranked result carries
reasons,warningsandbadges; every suppressed row carriessuppressedBy.
Policies and overrides
A policy is a declarative bundle of hard gates, score weights and a refusal bar. Presets:
| Gate | strict | default | degen |
|---|---|---|---|
minLiquidityUsd | 10 000 | 1 000 | none |
requireMarketData | true | false | false |
suppressImpersonation | true | true | false |
minMarketScore | none | none | none |
minAgeDays | 1 | none | none |
requireRegistry (verifiedOnly) | false | false | false |
/v2/search and /v2/resolve default to default; the curator search
GET /v2/lists/search-tokens defaults to strict.
Each gate can be overridden per request:
| Param | Accepts | Effect |
|---|---|---|
minLiquidityUsd | number ≥ 0, or none | Suppress below this liquidity (gate_min_liquidity). Registry-attested mints are exempt |
minAgeDays | integer ≥ 0, or none | Suppress tokens younger than this (gate_new_token) |
minMarketScore | integer 0–100, or none | Suppress tokens whose known score is below this (gate_min_market_score) |
requireMarketData | true, false | Suppress tokens with no market snapshot (gate_no_market_data) |
suppressImpersonation | true, false | Suppress likely impersonators of a protected symbol (gate_impersonation) |
verifiedOnly | true, false | Suppress mints without a curated-registry variant (gate_unverified) |
none, null and off all disable a numeric gate; booleans also accept 1/0 and yes/no.
Out-of-range numbers and unknown policy values are 400s; an invalid policy echoes the valid
ids in details.policies.
Overrides change only the gate you name; score weights and the refusal bar always come from the
preset. The response's policy.gates is the effective document and policy.overrides lists what
you changed, so any result is reproducible from its own envelope.
Two rules are not overridable under any preset:
- Advisory gates: mints carrying a
blockedorcompromisedadvisory are always suppressed (gate_advisory_blocked,gate_advisory_compromised). Acautionadvisory is a warning, not a gate. See Advisories. - Tombstones: mints editorially deleted from the corpus are always suppressed
(
gate_tombstoned).
Registry-attested assets bypass the liquidity gate: it exists to filter scams and unknowns, not to
hide verified assets that settle off-AMM (RFQ or primary-issuance tokenized stocks and funds). Thin
tradability on those shows as a low_liquidity warning instead.
Reading the output
reasonsexplain rank.warningsare caution signals on a token that is still ranked.suppressed[].suppressedBynames the gate that removed a candidate. All three vocabularies are enumerated below and are a stable contract: new codes may be added, existing ones are not renamed.suppressedrows are never truncated bylimit. Loosen the gate, or switch todegen, to see them ranked instead.badgesare free-form labels:curated:<list>for curated membership,tier1,tier2,tier3,grade:A|B|C(the same market grade v1 exposes, computed from the token's own liquidity, market cap, holders, volume and age) andadvisory:<status>. A token with too little market data to score carries nograde:badge.claims.attestationsare the evidence behind claim credibility:curated_list,registry_variant,market_dominance,deep_liquidity,sustained_activity,established_age,broad_holder_base, each with a human-readabledetail.verifiedistruewhen a curated-registry variant exists for the mint.
Explanation codes
reasons
| Code | Meaning |
|---|---|
mint_match | Query was this exact mint address |
exact_symbol_match | Symbol equals the normalized query |
exact_name_match | Name equals the normalized query |
symbol_prefix_match | Symbol starts with the query |
name_match | Name contains the query |
alias_match | Reserved for alias matches; not emitted |
curated_list_member | Mint is in one of the curated lists |
registry_variant | Mint is a curated-registry variant |
market_leader | Dominant market among the candidates claiming this symbol |
deep_liquidity | Liquidity of at least $1M |
high_activity | 24h volume of at least $250k |
established_token | First seen at least 90 days ago |
strong_execution_quality | Execution-quality score of at least 70 (tight, deep markets) |
warnings
| Code | Meaning |
|---|---|
low_liquidity | Liquidity below $10k, still ranked (the mint is registry-attested or the gate is off) |
no_market_data | No market snapshot available |
possible_impersonation | Claims a protected symbol, is not the protected holder, is not registry-attested, and is young or shallow |
symbol_collision | Claims a protected symbol without being its holder, but is established enough not to look like an impersonator |
suspicious_characters | Homoglyphs or invisible characters in the symbol or name |
new_token | Younger than 7 days |
stale_data | Market data older than 30 minutes |
high_bot_volume | More than 60% of volume attributed to bots |
concentrated_holders | Top-10 holders own more than 50% of supply (registry-attested mints exempt) |
unverified | No curated-registry variant for this mint |
weak_market_score | Known market score below 40 |
advisory_caution | The mint carries a caution advisory; see Advisories |
suppressedBy
| Code | Gate | Overridable |
|---|---|---|
gate_tombstoned | Mint editorially deleted from the corpus | no |
gate_advisory_blocked | Mint carries a blocked advisory | no |
gate_advisory_compromised | Mint carries a compromised advisory | no |
gate_min_liquidity | Below minLiquidityUsd (registry-attested mints exempt) | minLiquidityUsd |
gate_no_market_data | No market snapshot and requireMarketData is on | requireMarketData |
gate_impersonation | Likely impersonator of a protected symbol | suppressImpersonation |
gate_min_market_score | Known market score below minMarketScore | minMarketScore |
gate_new_token | Younger than minAgeDays | minAgeDays |
gate_unverified | Not in the curated registry and verifiedOnly=true | verifiedOnly |
Resolve: confidence or refusal
GET /v2/resolve runs the same pipeline over a fixed candidate window and answers with one of
three statuses, always with HTTP 200 when the request is valid:
resolved— the best candidate clears the policy's refusal bar and beats the runner-up by a margin.best.confidenceis 0–1; an exact mint paste is1.ambiguous— several credible claimers exist, typical for an unprotected symbol shared by unrelated tokens. Showcandidates(at most 5, best first) and let the user pick.no_confident_match— nothing clears the bar. A confident-looking wrong answer is the worst possible output, so "I don't know" is a first-class response.
Each policy has its own refusal bar: strict refuses most readily, degen least.
Cost
Unique queries can reach the live provider, so /v2/search, /v2/resolve and
/v2/lists/search-tokens share a per-key budget of 120 calls per 10 minutes by default.
Identical queries within the 30-second cache window do not count. See
Provider lookup budget.