> ## 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`       |

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

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

## Reasons

[`RiskReasonCode`](/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.

## 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` tells you that a token has a high tax or failed a sell. The numbers behind those reasons come from the contract simulator, which runs a buy and a sell against the token's pool and records what happened.

<Note>
  The simulator is in beta. Each run analyzes one pool, and pools with custom logic such as Uniswap V4 hooks are still being refined.
</Note>

1. Submit an analysis with [`simulateTokenContract`](/api-reference/mutations/simulatetokencontract). It returns a `simulationId` at once and the analysis runs in the background.
2. Read the outcome with [`getSimulateTokenContractResults`](/api-reference/queries/getsimulatetokencontractresults), passing that `simulationId`, or subscribe to [`onSimulateTokenContract`](/api-reference/subscriptions/onsimulatetokencontract) for the token.

```graphql theme={null}
mutation AnalyzeToken {
  simulateTokenContract(
    input: {
      simulateLiveContractInput: {
        contractAddress: "0x89d8cb38067b55f820f29a9e12d0ce18682a2bfc"
        networkId: 8453
      }
    }
  ) {
    result
    simulationId
    error
  }
}
```

```graphql theme={null}
query TokenTaxes {
  getSimulateTokenContractResults(
    contractAddress: "0x89d8cb38067b55f820f29a9e12d0ce18682a2bfc"
    networkId: 8453
    simulationId: "<simulationId from the mutation>"
  ) {
    results {
      status
      verdict
      verdictReason
      swap {
        buyTax
        sellTax
        buySuccess
        sellSuccess
      }
      liquidity {
        pairAddress
      }
    }
  }
}
```

Reading a result:

* `verdict` is the answer: `TRADEABLE`, `HONEYPOT`, or `INDETERMINATE` with a `verdictReason` such as no sell route or an unsupported venue. `status` only tracks the pipeline, and `buySuccess` / `sellSuccess` are true on indeterminate rows too, so read `verdict` first.
* `swap.buyTax` and `swap.sellTax` are decimal fractions as strings. `"0.05"` is 5% and `"1"` is 100%. A honeypot usually shows `sellTax: "1"` with `sellSuccess: false`.
* `liquidity.pairAddress` is the pool the run traded through. Tax is a property of the pool, so two runs on the same token can differ when they route through different pools. On Uniswap V4 this is a 32-byte pool ID.
* A submission writes a `PENDING` row first. The finished result lands as a second row under the same `uuid`, usually within seconds. Read the row that has a `verdict`.
* Omit `simulationId` to read every stored analysis for the token, newest block first. An empty list means the token has never been analyzed, so submit one. Rows from before the 2026 rebuild can have `status: FAILURE` and no `verdict`.
* One submission per token and network every five minutes. A second one returns a `TOO_MANY_REQUESTS` error naming the retry time.

The three simulator endpoints need a Growth or Enterprise plan.

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

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

* `filterTokens` hides tokens with `isScam: true` by default. Pass `includeScams: true` 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.
