---
title: "Is a token safe"
method: GET
path: "/security/token/{chain}/{address}"
tags: ["Token safety"]
---

# Is a token safe

`GET /security/token/{chain}/{address}`

## Request

- Base URL: `https://api.getchord.xyz/v1`
- URL: `https://api.getchord.xyz/v1/security/token/{chain}/{address}`
- Auth: none declared

Chord's safety report for one token: the same report the Ask analyst, the trade dock and the trade card read.

**What runs**: on the EVM chains, Chord's own contract scan (proxy wiring and who can upgrade it, the owner and what the owner can do: mint, block wallets, pause, change taxes or limits), a $20 buy and its sell back through Chord's router simulated as a test wallet (nothing is sent), the transfer-tax probe, GoPlus, Sourcify and Chord's own tape screen (wash trading, buyer clusters, rugs, buyers who cannot sell, a copied ticker). On Solana: RugCheck, GoPlus, Jupiter and the screen of Chord's Solana tape (mint and freeze authority, Token-2022 extensions, LP lock, holders, the creator's history). A source that does not answer leaves its checks `unknown` and the report `partial`; it is never read as a pass.

**Use it for**: "is this token safe to buy", a rug or honeypot check before a trade, an agent's pre-trade gate (refuse `avoid`, warn on `caution`).

**Notes**
- Cached 10 minutes (2 to 3 minutes when a source did not answer, seconds when nothing could test selling an unvetted token or the check was cut short on Chord's side; such a partial report is sent `Cache-Control: private, max-age=10`). A report built cold on an EVM chain can take up to about 20 seconds. An address with no contract answers 404 at once.
- A report already cached answers anyone. Without an API key (or an Ask session), one IP builds at most 10 new reports every 10 minutes, and every such caller together a limited number a minute; past either the answer is 429 or 503 `BUSY` with `Retry-After`, and nothing is checked. Send an `X-API-Key` for more.
- `verdict` is decided in code from `checks`. No verdict rests on GoPlus alone: when only GoPlus answered, the report is `partial` and says Chord's own checks did not run. A reading from GoPlus names it "GoPlus (Powered by Go+ Security)".
- A Solana mint is used exactly as given (base58 is case-sensitive).

## Path parameters

- `chain` string, required
- `address` string, required

## Response `200`

The report.

- TokenRiskReport: Chord's safety report for one token.
  - `chain` union, required: The chain id, or `solana`.
    - integer
    - 'solana'
  - `address` string, required: The token (0x, lower-cased) or the Solana mint (case kept).
  - `symbol` string, nullable: As the contract or the token list names it: chosen by whoever launched the token.
  - `name` string, nullable
  - `verdict` 'avoid' | 'caution' | 'ok' | 'unknown', required: Decided in code from the checks, never by a model. `avoid`: it cannot be sold, a sell tax of 30% or more, a scam verdict of Chord's tape screen, or a copy of a listed token's ticker. `caution`: a check that warns (taxes of 5 to 30%, an owner who can mint, block wallets or pause, code one wallet can upgrade, unverified source, unlocked liquidity one provider can pull, top 10 holders over 60% …). `ok`: none of that, with two independent sources answering and a sell test passing. `unknown`: too few sources, or nothing could test selling it. Never read `ok` as a guarantee.
  - `score` integer, nullable, required: 0 (worst) to 100, in the verdict's band; null when the verdict is `unknown`.
  - `checks` RiskCheck[], required: Every check, in a fixed order.
    - `id` string, required: Stable id, snake_case: `honeypot`, `buy_tax`, `sell_tax`, `transfer_tax`, `round_trip`, `owner_can_mint`, `blacklist`, `pausable`, `owner_privileges`, `hidden_owner`, `proxy_upgradeable`, `unverified_source`, `lp_unlocked`, `top10_holders`, `creator_holds`, `creator_history`, `tape_screen`, `impostor_ticker`, `own_checks` …; Solana adds `freeze_authority`, `mint_authority`, `token2022_extensions`, `mutable_metadata`, `liquidity` …
    - `label` string, required: Short English label (`Sell tax`, `Owner can mint`).
    - `status` 'pass' | 'warn' | 'fail' | 'unknown', required: `unknown` = the source that reads it did not answer, or nothing could test it. Never `pass` for a check that did not run.
    - `detail` string, required: One sentence with the measured number (`Selling loses 40% to the token's own tax (Chord simulation 40%, GoPlus 40%).`).
    - `source` string, required: Who read it, in words, at most 60 characters (`Chord simulation`, `Chord contract scan`, `Chord tape`, `RugCheck`, `Sourcify`). A reading from GoPlus says `GoPlus (Powered by Go+ Security)`.
  - `facts` object, required: The numbers behind the checks: `buyTaxPct`, `sellTaxPct`, `transferTaxPct`, `honeypot`, `owner`, `ownerRenounced`, `proxy`, `implementation`, `upgrader`, `verifiedSource`, `mintable`, `blacklist`, `pausable`, `lpLockedPct`, `top10Pct`, `holders`, `creator`, `creatorPct`, `screenLevel`, `screenReasons`, `simulation` (Chord's $20 buy and sell back: status, taxes, round trip), `reasons` (the counted reasons, worst first), `answered` / `missing` (the sources), `goplusOnly` (only GoPlus answered: the report is partial). Solana adds `mintAuthority`, `freezeAuthority`, `token2022Extensions`, `permanentDelegate`, `liquidityUsd`, `pools`, `topHolders`, `jupiterVerified`, `rugcheckScore` …
  - `sources` object[], required: Where to read it yourself (explorer, GoPlus, RugCheck, Sourcify, Jupiter).
    - `label` string
    - `href` string
  - `checkedAt` integer, required: Unix time, milliseconds — when the server built this answer.
  - `partial` boolean, required: True when at least one source did not answer, or when GoPlus was the only one that did.
  - `vetted` boolean, required: On a list Chord trusts (stock / ETF / bridged list token, the bridge provider's list, Monad's verified list, a registry anchor; on Solana Jupiter-verified majors): the issuer's own powers (mint, freeze, pause, upgrades) are listed but do not raise the verdict. Taxes and the sell test still count.

## Other responses

- `400`: `UNSUPPORTED_CHAIN` (a chain Chord does not check, or one not served yet) or `INVALID_ADDRESS`.
- `404`: `NOT_A_CONTRACT`: the chain answered and there is no contract at this address. `NOT_A_MINT`: no Solana source knows this address as a token.
- `429`: `RATE_LIMITED`: without an API key, this IP built its 10 new reports of the last 10 minutes (`Retry-After`); cached reports still answer. Or `RATE_LIMIT_EXCEEDED`, the per-minute limit of every route.
- `503`: `BUSY`: too many new reports are being built for callers without a key right now (`Retry-After`). `UNAVAILABLE`: the check could not run just now. Retry; do not treat either as a clean result.

---

[API](https://skmtc.dev/getchord/apis/chord-api.md) · [All operations](https://skmtc.dev/getchord/apis/chord-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getchord/apis/chord-api/revisions/d3bc4640fea0?raw)
