Tokens/token_safety
Is this token safe?
$0.02per call after 25 free a daySimulates a real holder selling, then checks if liquidity can be pulled, the creator's record, insider wallet networks, issuer powers (mint, freeze, Token-2022 traps), verification, liquidity, holders and age, for one verdict.
Run before buying, accepting or recommending a token. Answers SAFE, CAUTION or AVOID with exact reasons from chain and market data.
Saves money. Flags tokens you can't sell, liquidity the creator can pull, creators who have rugged before, hidden insider wallets and issuers who can freeze or take your tokens, before you buy. Regulated stablecoins' powers count as expected.
Call it
| Transport | How |
|---|---|
| HTTP | POST /api/tools/token_safety with a JSON body of the inputs below. |
| MCP | tools/call with name token_safety on /mcp. |
Inputs
| Name | What it's looking for | Where to get it |
|---|---|---|
tokenstring (token address), required | The token's address. | From find_token (for a ticker) or tokens (for a wallet's tokens). |
network"mainnet-beta" | "devnet", optional | Default "mainnet-beta" (real money). | "devnet" only for test wallets. |
Returned fields
Every field the tool returns, what it is, and exactly how it's worked out.
| Field | What it is | How it's worked out |
|---|---|---|
verdict"SAFE" | "CAUTION" | "AVOID" | The answer. AVOID: at least one check failed. CAUTION: at least one warning. SAFE: no warnings. | The worst check wins: any fail is AVOID, any warn is CAUTION, otherwise SAFE. |
summarystring | One sentence explaining the verdict. | Built from the failed and warning checks. |
about.symbol / namestring | null | Ticker and name. | Jupiter token data. |
about.decimalsnumber | Decimal places. | The on-chain token account. |
about.supplystring | Total supply in whole tokens. | On-chain supply / 10^decimals, exact. |
about.token_program"spl-token" | "token-2022" | Which token program it uses. | The owner of the token's account. |
about.who_can_mintstring | null | Who can create more tokens. null means nobody (fixed supply). | The on-chain mint authority. |
about.who_can_freezestring | null | Who can freeze holders' tokens. null means nobody. | The on-chain freeze authority. |
about.extensionsstring[] | Token-2022 extensions turned on. | Read from the token's account. |
about.usd_price / liquidity_usd / holders / top10_share_pct / first_tradednumber | string | null | Market facts the checks use. | Jupiter token data. top10_share_pct is the share the 10 biggest holders own. first_traded is when its first pool was made. |
about.creator / creator_tokens_launchedstring | number | null | The wallet that created the token, and how many tokens it has launched. | Jupiter token data. |
about.metadata_can_changeboolean | null | Whether the name and logo can still be changed. | RugCheck's report of the token's metadata. |
checks[].namestring | Which check: sell_test, liquidity_pull, creator_history, insiders, metadata, verified, mint_authority, freeze_authority, extension:<name>, liquidity, holder_concentration, age, known_stablecoin, market_data or rugcheck_data. | A fixed list. market_data or rugcheck_data (warn) shows up only when Jupiter or RugCheck can't be reached. The checks that need them are then skipped, not guessed. |
checks[].result"pass" | "info" | "warn" | "fail" | How the check came out. info means notable but expected, like a regulated stablecoin's freeze power. | Sell test: fail if the token blocked a real holder's simulated sale, warn if there's no route to sell or it failed for another reason. Liquidity pull: fail when over 20% of the liquidity is unlocked and comes from 1 or 2 providers (warn for verified tokens), warn for 3 to 9 providers, info for established tokens (Jupiter-verified and trading 90+ days). Creator: fail if they have rugged before, warn if an unverified token's creator launched 20+ tokens or still holds over 20%. Insiders: warn over 10% of supply, fail over 30%, counting only networks of up to 500 wallets; unknown (info) when RugCheck's numbers add up to more than the whole supply. Metadata: warn if an unverified token's name and logo can change. Liquidity: fail under $10k, warn under $100k. Top 10 holders: warn over 50%, fail over 80% (established tokens: info up to 80%, warn over; info for known stablecoins and Jupiter-verified liquid staking tokens). Age: warn under 24 hours. Permanent delegate fails, except a known issuer's delegate (xStocks, Backpack Securities, Paxos), which warns and names the issuer. Frozen-by-default and non-transferable fail. Mint and freeze powers warn unless it's a known stablecoin or an established token (Jupiter-verified and trading 90+ days), where they are info and name who holds them. |
checks[].detailstring | The fact behind the result, in plain words. | Built from the data. |
checks[].source"on-chain" | "jupiter" | "rugcheck" | "simulation" | Where the fact came from. | on-chain for token data, jupiter for market and creator data, rugcheck for liquidity locks, insiders and creator history, simulation for the sell test. |
historyobject | null | What changed since Pulse first checked this token, when Pulse has been watching it. null when it hasn't. | Pulse watches young tokens (under 3 days old) for 7 days after it first checks them, whether it found them on Jupiter's activity lists or someone ran token_safety on them, and re-reads them every 2 hours. Checking a young token starts the watch, so a later check shows what changed. |
history.watched_since / watching_until / verdict_then / found_instring | When the watch started and ends, the verdict Pulse gave then, and how the token was found. | Stored when the watch started. |
history.then / latestobject | The first and the newest reading: listed, liquidity_usd, usd_price, holders, top10_share_pct, who_can_mint, who_can_freeze (latest also has at). | then is what this tool reported when the watch started. latest comes from Jupiter (market numbers) and the chain (authorities). A value no source answered is null. |
history.changes[]{ at, what, result, detail, source }[] | Each change once, at the first reading that showed it: liquidity_pulled (fail), price_crashed (fail), liquidity_halved, holders_halved, top10_up, mint_authority_moved, freeze_authority_moved (warn), or mint_authority_revoked / freeze_authority_revoked (info). | Liquidity pulled: down 90%+ or no longer listed by Jupiter while Jupiter answers. Price crashed: down 90%+. Halved: down 50%+. Top 10 up: their share rose 15+ points. Authorities: a different wallet now holds the power, or it was revoked. Empty means no change crossed those lines. |
Limits
- The check doesn't make a token safe, and it can't. It looks for the known ways people get robbed with a token. "SAFE" really means "none of the traps we know about are present." Every rule exists because it matches a real scam.
- It can't catch everything, such as a team abandoning a project or insiders it has no data on, and SAFE says nothing about whether the price will rise or fall.
- history is not part of the verdict: the verdict is about the token now; history shows how it got here. Liquidity pulled since Pulse first saw it is the classic rug.
- The sell test sells about $20 from a real holder's wallet in a simulation only: nothing is sent, and no funds move.
- Top-holder share counts accounts, which can include exchanges and liquidity pools.
- Established tokens (Jupiter-verified and trading for 90+ days) are judged on traps, not on how they're run: a mint or freeze authority, unlocked liquidity and a big treasury show up as info naming who holds them, because bridges, issuers and market makers run real tokens that way. New tokens get the strict checks, since that's when liquidity gets pulled.