> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Risk

> Read Codex's risk verdict, score, coverage and reason codes for a token or pair, and filter or rank by them.

Codex assesses tokens for scam and rug signals and returns one answer: a **verdict**, the **score** behind it, how much **contract analysis** it rests on, and the **reasons** that fired. Use it to warn users and build your own screening. It is a warning signal, not a safety guarantee.

## Where to read it

| | Tokens (`token`, `tokens`, `filterTokens`) | Pairs (`filterPairs`) |
| - | - | - |
| Verdict | `risk.verdict` | `riskVerdict` |
| Score | `risk.score` | `riskScore` |
| Coverage | `risk.coverage` | `riskCoverage` |
| Reasons | `risk.reasons` | `riskReasons` |
| Last changed | `risk.flaggedAt` | `riskFlaggedAt` |
| Buy tax | `risk.buyTax` | `riskBuyTax` |
| Sell tax | `risk.sellTax` | `riskSellTax` |

Pair fields describe the pair's token of interest (the one named by `quoteToken`), not the pool itself.

A null `risk`, or a null field inside it, means Codex has no assessment. Treat it as unknown, never as safe.

## Verdicts

| Verdict | Meaning |
| - | - |
| `SCAM` | Proven by mechanical evidence (for example, a repeated honeypot simulation or a 100% transfer fee) or labelled a scam by a moderator. |
| `HIGH_RISK` | Score of 70 or more. |
| `CAUTION` | Score from 40 to 69. |
| `NEUTRAL` | Score below 40. Reasons can still be present. |
| `VERIFIED` | A moderator marked the token not-a-scam. |
| `VERIFIED_CONTESTED` | A moderator marked it not-a-scam, but mechanical evidence disagrees. |

`SCAM`, `VERIFIED` and `VERIFIED_CONTESTED` come from proof or a human decision, not the score, so their `score` is usually null. A high score alone never produces `SCAM`.

## Score

Each reason adds points, and a 15-point bonus applies when reasons from three or more families fire together. The total is capped at 100. The score is a weighted heuristic, not a probability: 70 does not mean a 70% chance of a scam.

Not every reason adds points. Authority reasons (`AUTH_*`), such as a Solana mint or freeze authority, report a capability without scoring it, so you can't rebuild the score by counting reasons.

## Coverage

Coverage says how much contract analysis (simulated buys and sells, static checks) the verdict rests on. It doesn't say what the analysis concluded.

| Coverage | Meaning |
| - | - |
| `ANALYZED` | Contract analysis ran and reached a decisive result. |
| `INCONCLUSIVE` | Contract analysis ran but was not decisive. |
| `NOT_ANALYZED` | No contract analysis. The verdict rests on holder, liquidity, trading and moderation signals only. |
| `STALE` | Earlier contract analysis has expired and is waiting to be re-run. |

New values can be added to this enum. Treat unknown values as `NOT_ANALYZED`.

A `NEUTRAL` token with `NOT_ANALYZED` coverage has had no honeypot or tax check. Show that differently from `NEUTRAL` + `ANALYZED`.

## Reasons

[`RiskReasonCode`](https://docs.codex.io/api-reference/enums/riskreasoncode) values are grouped by prefix:

| Prefix | What it covers |
| - | - |
| `PROOF_*` | Mechanical proof, such as a honeypot or non-transferable token. |
| `LABEL_*` | Moderator decisions. |
| `AUTH_*` | Owner or authority capabilities: mint, freeze, pause, transfer hooks. |
| `TAX_*` | High buy or sell tax, or an unconfirmed honeypot result. |
| `LIQ_*` | Minimal, unlocked, or suddenly removed liquidity. |
| `HOLD_*` | Supply concentrated in the top 10, the developer, snipers, bundlers or insiders. |
| `FLOW_*` | Suspicious trading: one-way flow, wallet farms, wash or bundled trading. |
| `REP_*` | Creator reputation and imitation of known tokens. |

New codes are added over time. Handle unknown codes gracefully, and don't treat an empty list as proof the token is clean.

## Freshness

Codex re-assesses tokens in the background as new data arrives; queries read the latest stored result. `flaggedAt` is the Unix time the assessment last **changed**. A re-check that reaches the same result doesn't update it.

A new token usually gets its first assessment within a few minutes of its first pool. Until then `risk` is null. Early assessments often have `NOT_ANALYZED` coverage, and the contract analysis fills in later. There is no push when an assessment lands, so poll [`tokens`](https://docs.codex.io/api-reference/queries/tokens) if you need it.

## Examples

### Read one token

```graphql theme={null}
query TokenRisk {
  token(input: { address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", networkId: 1 }) {
    symbol
    risk {
      verdict
      score
      coverage
      reasons
      flaggedAt
    }
  }
}
```

### Hide risky tokens from a list

```graphql theme={null}
query SaferTokens {
  filterTokens(
    filters: { riskVerdicts: [NEUTRAL, VERIFIED], riskCoverages: [ANALYZED] }
    rankings: { attribute: volume24, direction: DESC }
    limit: 25
  ) {
    results {
      token {
        symbol
        risk {
          verdict
          score
        }
      }
    }
  }
}
```

Values inside one filter are ORed; different filters are ANDed. Filtering by verdict also drops unassessed tokens.

### Find likely honeypots among pairs

```graphql theme={null}
query HoneypotPairs {
  filterPairs(
    filters: { riskReasons: [PROOF_HONEYPOT_SIM, TAX_HONEYPOT_UNCONFIRMED] }
    rankings: { attribute: riskScore, direction: DESC }
    limit: 25
  ) {
    results {
      pair {
        address
        networkId
      }
      riskVerdict
      riskScore
      riskReasons
    }
  }
}
```

`filterTokens` and `filterPairs` both accept `riskVerdicts`, `riskCoverages`, `riskReasons`, `riskScore` and `riskFlaggedAt` filters, and both can rank by `riskScore` or `riskFlaggedAt`.

## Get the actual tax numbers

`risk.buyTax` and `risk.sellTax` return the tax the token charges on each side of a trade, measured by the token's latest decisive contract analysis. The verdict and risk reasons reflect the analysis available at the last risk assessment. On pairs, `riskBuyTax` and `riskSellTax` give the tax of the pair's token of interest.

Each side is measured on its own simulated trade: the buy tax on the buy, the sell tax on the sell. Pool fees, Uniswap V4 hook fees and launchpad platform fees are not tax and are left out. A token with a 9% tax on a launchpad that also charges a 1% fee reads `buyTax: 0.09` and `sellTax: 0.09`. A tax-free token in a pool with a 1% hook fee reads `0` where Codex can measure that side.

```graphql theme={null}
query TokenTaxes {
  token(input: { address: "TOKEN_ADDRESS", networkId: 56 }) {
    symbol
    risk {
      verdict
      coverage
      buyTax
      sellTax
    }
  }
}
```

Reading the values:

* They are fractions as numbers: `0.05` is 5%.
* `null` means no decisive analysis could measure that side on its own. Treat it as unknown, not as 0%. On some venues only one side can be separated from the venue's fees, for example the buy on Uniswap V3 and V4 pools, so the other side is `null`.
* A honeypot returns `sellTax: null` because its test sale failed, so no sell tax was measured. Its `buyTax` is usually set. Read the verdict and reasons for the honeypot itself.
* The tax can be newer than `verdict` and risk reasons such as `TAX_SELL_HIGH`. A new analysis shows up at once, while the verdict and reasons update on the token's next assessment.
* You can't filter or rank by tax. To find taxed tokens, filter on `riskReasons: [TAX_SELL_HIGH]` or `[TAX_BUY_HIGH]`, which fire at 10% or more.

For Solana Token-2022 mints, `extensions.token2022.transferFeeConfig` on [`TokenExtensions`](https://docs.codex.io/api-reference/types/tokenextensions) exposes the configured fee schedules separately from measured risk taxes. A known configured fee can coexist with `risk.buyTax: null` and `risk.sellTax: null` when no decisive simulation established the per-side measurements. The effective fee depends on the active epoch, transfer amount, maximum fee and rounding. Plain SPL tokens have no transfer-fee configuration, so their measured risk taxes remain null.

## How this relates to `isScam` and `potentialScam`

Risk filters are opt-in. They don't change the existing scam filters:

* `isScam` is a manual label on a small set of tokens. `true` means a moderator marked the token a scam (`LABEL_MANUAL_SCAM`), `false` means a moderator verified it (`VERIFIED`), and `null`, which covers almost every token, means it hasn't been reviewed. Read it from `token.isScam`. The result-level `isScam` on `filterTokens` results is always null.
* `filterTokens` hides tokens with `isScam: true` by default. Automated `SCAM` verdicts are not hidden unless you filter on `riskVerdicts`. Pass `includeScams: true` inside `filters` to include them, which you'll need when filtering for `SCAM` verdicts.
* `isVerified: true` keeps only tokens with `isScam: false`. It isn't the same as `riskVerdicts: [VERIFIED]`.
* `potentialScam` and `potentialScamReasons` are an older automated flag. They're still available, but `risk` is the more complete signal.

### Reading `potentialScamReasons`

* The reasons are recomputed from the token's current state each time it is re-scored. A reason drops off as soon as its condition stops holding, and there is no timestamp for when a reason fired.
* An empty list means nothing fired. It is also returned when a check was skipped for missing data, so `[]` is not proof the token is clean.
* `SniperConcentration` fires when wallets that bought in the first 5 seconds currently hold at least 50% of the supply. It is only computed where sniper stats exist (launchpad tokens).
* `MinimumLiquidity` fires when the token's `liquidity` is \$10 or less. `LiquidityUnknown` means liquidity could not be read, so the liquidity checks did not run.
* See [`PotentialScamReason`](https://docs.codex.io/api-reference/enums/potentialscamreason) for every value.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.