RISK-DATA API DOCS
GET /api/v1/token-risk
curl "https://tnt-audit.com/api/v1/token-risk?mint=<MINT_ADDRESS>" \
  -H "Authorization: Bearer tnt_sk_your_key_here"
{
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "safety_score": 78,
  "maturity_capped": false,
  "market_health_capped": false,
  "contract_risk_capped": false,
  "rugged_capped": false,
  "caps_triggered": [],
  "dominant_cap": null,
  "cluster_analysis": "complete",
  "insider_clusters": [
    {
      "funder": "9xQe...k2Pd",
      "wallets": [
        "7uF3...aZ1",
        "3mN8...qR2"
      ],
      "funder_class": "unknown",
      "funder_label": null,
      "funder_confidence": null,
      "false_positive_likely": false
    }
  ],
  "insider_holder_count": 2,
  "mint_authority": {
    "revoked": true,
    "address": null
  },
  "freeze_authority": {
    "revoked": true,
    "address": null
  },
  "contract_renounced": true,
  "honeypot_risk": false,
  "lp_locked": {
    "locked": true,
    "percent": 100
  },
  "rugged": false,
  "jup_verified": true,
  "deployer_address": "9xQe...k2Pd",
  "hidden_owner": false,
  "permanent_delegate": false,
  "buy_tax_percent": null,
  "sell_tax_percent": null,
  "dev_wallet_percent": 1.8,
  "token_program": "standard",
  "vesting_locks": [],
  "holder_distribution": {
    "risk_level": "LOW",
    "largest_holder_percent": 4.2,
    "top10_percent": 22.7,
    "holder_count": 20
  },
  "market": {
    "price_usd": 0.0000412,
    "liquidity_usd": 84210,
    "volume_24h_usd": 512300,
    "price_change_24h_percent": 12.4,
    "age_days": 3
  },
  "checked_at": "2026-07-18T12:00:00.000Z"
}

Works out of the box with ChatGPT Custom GPT Actions (just paste the URL). For Claude, Gemini, or agent frameworks like LangChain/CrewAI, use this spec as the schema source for your own tool integration — most of those need a small adapter, LangChain's OpenAPISpec.from_url() being the one that imports it directly.

Response fields

safety_score

0–100. Weighted from authorities, holder concentration, liquidity, volume, and real insider-cluster penalties.

insider_clusters

Wallets that share a first-funder — an on-chain-provable insider/sniper signal, not a guess. Each cluster also carries funder_class, funder_label, funder_confidence, and false_positive_likely: known CEX/bridge hot wallets and confirmed high-fan-out infra funders stay visible here but no longer count toward the insider penalty in safety_score.

cluster_analysis

"pending" on a token's first-ever check (cluster trace runs in the background), "complete" once the trace finishes.

mint_authority / freeze_authority

Whether each authority is revoked, and its address if still active.

honeypot_risk / lp_locked

honeypot_risk (boolean) and lp_locked ({ locked, percent }) from RugCheck. null means it could not be checked, not "safe."

holder_distribution

Largest holder %, top-10 %, risk level, and holder_count — the number of accounts in Solana’s top-20-largest-holders response (a real RPC limit, not a full holder count for widely-held tokens like BONK or USDC).

market

Live price, liquidity, 24h volume, 24h change, and token age from DexScreener.

hidden_owner / permanent_delegate

hidden_owner and permanent_delegate (booleans) from RugCheck's risk list. permanent_delegate is a Token-2022 extension letting that address move or burn ANY holder's tokens without permission — a severe risk. null means not checked, never a false "safe".

buy_tax_percent / sell_tax_percent

buy_tax_percent / sell_tax_percent — Token-2022 transfer-fee extension. Solana's transfer fee is symmetric, so both carry the same value. null means the mint has no such extension (not a failed check).

dev_wallet_percent

dev_wallet_percent — the deployer's own on-chain holding as % of total supply. A distinct concentration signal from holder_distribution.top10_percent, since the deployer can hold a large stake while sitting outside any top-10 cutoff.

token_program / contract_renounced

token_program: "standard" if the mint uses one of Solana's two canonical token programs, "nonstandard" otherwise. contract_renounced: convenience boolean for mint_authority.revoked && freeze_authority.revoked.

caps_triggered / dominant_cap

caps_triggered lists every scoring cap that fired for this mint (reason + cap value); dominant_cap is the single tightest one — the actual reason safety_score is what it is, not just a number. explanation gives that same reason as a ready-made sentence.

vesting_locks

vesting_locks lists known on-chain vesting/lock contracts found among this mint's top holders (Streamflow, v1). A large holder genuinely locked for the long term is scored differently from a freely-tradeable whale — the score already accounts for this, holder_distribution.top10_percent stays the raw on-chain figure.

Every response also includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers — plus X-Credit-Balance-Usd once you have a paid tier or credit balance — so your bot can track its quota without ever hitting a 429.

On a token's first-ever check, cluster_analysis returns "pending" while the trace runs in the background — re-check the same mint shortly after, or subscribe to a safety_score webhook below to get pushed a notification instead of polling.

Rate Limiting

Every key gets 15 free requests per calendar day (UTC). Go over that with no call-credit balance and you get a 402, not a silent block — top up or subscribe and the same key keeps working immediately.

5 free MCP calls/day, no signup — built for bots & AI agents. Then a free key (15/day) or x402 pay-per-call.

X-RateLimit-Limit

Your daily quota. Empty on unlimited/admin-issued keys.

X-RateLimit-Remaining

Requests left before the free quota runs out today.

X-RateLimit-Reset

ISO timestamp of the next quota reset (next UTC midnight, or your subscription renewal date).

X-Credit-Balance-Usd

Your current call-credit balance, once you have one.

What happens over the limit

You get an HTTP 402 with a JSON body — limit, used, reset_at, overage_rate_usd, and an upgrade_url. No retries needed: as soon as you top up credit or subscribe, the same key starts working again on the very next call.

HTTP/1.1 402 Payment Required
X-RateLimit-Limit: 15
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-07-24T00:00:00.000Z

{
  "error": "Daily free-tier limit reached and call-credit balance is empty",
  "limit": 15,
  "used": 16,
  "reset_at": "2026-07-24T00:00:00.000Z",
  "overage_rate_usd": 0.02,
  "upgrade_url": "https://tnt-audit.com/risk-api#billing",
  "note": "Top up call credits or subscribe on the upgrade_url page — overage is billed at $0.02/call once you have a balance."
}

Check X-RateLimit-Remaining before firing off a batch of calls — reading a header costs nothing, a wasted 402 does not.

Webhooks

Instead of polling token-risk on a schedule, subscribe once to a mint and a safety_score threshold — get a signed HTTP callback the moment it's crossed, in either direction.

POST /api/v1/webhooks/subscribe
Subscribe
curl -X POST "https://tnt-audit.com/api/v1/webhooks/subscribe" \
  -H "Authorization: Bearer tnt_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "threshold": 50,
    "condition": "below",
    "callback_url": "https://yourbot.example.com/webhooks/tnt"
  }'
Subscription created — 201
{
  "id": "8f2a1c3e-4b6d-4a1e-9c2f-1a2b3c4d5e6f",
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "threshold": 50,
  "condition": "below",
  "callback_url": "https://yourbot.example.com/webhooks/tnt",
  "active": true,
  "created_at": "2026-08-03T12:00:00.000Z",
  "webhook_secret": "whsec_9f8e7d6c5b4a3f2e1d0c...",
  "note": "Save webhook_secret now — it is shown only once and is required to verify the X-Webhook-Signature header on every delivery."
}
POST <your callback_url>
Delivered to your callback_url
X-Webhook-Signature: hmac-sha256(...)
{
  "id": "evt_19a2b3c4d5e6f7",
  "object": "webhook_event",
  "api_version": "v1",
  "created": 1785845700,
  "type": "risk_score.threshold_crossed",
  "data": {
    "object": {
      "subscription_id": "8f2a1c3e-4b6d-4a1e-9c2f-1a2b3c4d5e6f",
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "previous_score": 62,
      "current_score": 48,
      "threshold": 50,
      "condition": "below",
      "crossed_at": "2026-08-03T12:15:00.000Z"
    }
  }
}
Delivery & Retries

Delivered via QStash: on a non-2xx response or timeout, we retry up to 3 times with exponential backoff, then give up. Each event carries a unique id (evt_...) — store it and skip anything you have already processed, since retries resend the identical event. A 200 response marks the event delivered even if your own processing fails afterward, so persist or act on the payload before returning it.

Fires once per crossing, not on every check. Verify each delivery with the X-Webhook-Signature header and the webhook_secret from the subscribe response (shown only once). Call DELETE /api/v1/webhooks/{id} to unsubscribe.

Versioning & Changelog

The API is versioned in the URL (/api/v1/...). Within v1, existing fields are never removed, renamed, or repurposed — only added. Integrations should ignore fields they don't recognize rather than fail on them. A genuinely breaking change ships as /api/v2/..., with v1 kept running for a reasonable overlap period — never a silent in-place break.

Changelog
v1.202026-09-15
  • • insider_clusters: each cluster now carries funder_class ('cex' | 'infra' | 'likely_exchange_or_infra' | 'unknown'), funder_label, funder_confidence, and false_positive_likely. A shared first-funder that's a known exchange/bridge hot wallet, or matches a high-fan-out infrastructure pattern (thousands of funded accounts, micro-transfer rent payments, high tx frequency), stays visible in the response for transparency but no longer counts toward the insider penalty in safety_score -- fixes false positives we found live on CEX hot wallets being scored as insider clusters.
v1.192026-08-29
  • • Docs: added a runnable Python example for the x402 endpoint (openlibx402-client + solders) alongside the existing curl example -- shows a bot/agent developer the full 402 -> pay -> retry flow in ~10 lines instead of just the raw HTTP mechanics.
v1.182026-08-29
  • • Pay-per-call (unsubscribed PAYG) overage rate: $0.04 -> $0.02/call -- lowers the friction of a first trial for a new user who isn't ready to commit to the $45 subscription yet. As a result PAYG and x402 are now the same rate; x402's pitch was rewritten from "cheaper than PAYG" to "no account or key needed" -- the accurate differentiator.
v1.172026-08-28
  • • Subscription pricing change: monthly quota 1000 -> 5000 calls/30 days, subscribed overage $0.02 -> $0.015/call. Free (15/day), PAYG ($0.04/call unsubscribed), and x402 ($0.02/call) rates are unchanged -- pricing brought below the closest paid competitor (token-rugcheck via x402, $0.02/call for comparable commodity data) after a competitor-research review.
v1.162026-08-22
  • • Synced the public OpenAPI spec (openapi.json) with all 5 live API endpoints -- batch, history, webhook subscribe/list, signup, and trial -- previously only the 2 core token-risk endpoints were documented. Also fixed a stale x402 price left over from before the v1.13 cut (spec said $0.07, live price is $0.02).
  • • Added public/llms.txt -- a machine-readable index of the API built for LLM coding agents (Claude Code, Cursor, etc.) to onboard from directly, following the emerging llms.txt convention.
v1.152026-08-21
  • • Published an Agent Plugins 1.0 package (plugin.json + mcp.json, agent-plugins.org spec) — lets Agent Plugins-compatible clients discover and connect to the MCP server with no manual setup.
  • • Submitted a Codex-native plugin package to the awesome-codex-plugins directory (hashgraph-online/awesome-codex-plugins, PR #380) — HOL Plugin Scanner score 91/100, no critical/high findings, CI passing — pending maintainer review.
v1.142026-08-18
  • • Listed in the DeepSeek Harness (dsh-plugin) ecosystem — the repo now carries the dsh-plugin GitHub topic, making it discoverable by DSH plugin directories and the in-app plugin marketplace.
  • • Submitted a Security skill to the Solana Skills marketplace (sendaifun/skills, feeding solana.com/skills) — pending maintainer review.
v1.132026-08-13
  • • Price cut: pay-per-call $0.07 -> $0.04/call, subscribed overage $0.03 -> $0.02/call, subscription $49 -> $45 for 1000 calls/30 days, x402 $0.07 -> $0.02/call — brought in line with comparable market rates after reviewing direct competitors.
v1.122026-08-08
  • • New vesting_locks[] field — detects known on-chain vesting/lock contracts (Streamflow, v1) among a mint's top holders, so a large holder genuinely locked long-term no longer scores identically to a freely-tradeable whale.
  • • safety_score concentration scoring now uses a "freely tradeable" top10% that subtracts genuinely-locked supply (unless the lock is cancelable by its sender, or unlocking within 30 days) — holder_distribution.top10_percent itself stays the raw, unadjusted on-chain figure.
v1.112026-08-08
  • • Six new fields: hidden_owner, permanent_delegate, buy_tax_percent, sell_tax_percent, dev_wallet_percent, token_program, plus contract_renounced — all from the same RugCheck call, zero extra latency.
  • • safety_score now includes a new contractRiskCap tier (permanent_delegate, hidden_owner, tax, non-standard token_program) and a dev-wallet-% axis on the existing market health cap — a token can no longer score high on liquidity/volume alone while carrying a severe contract-level red flag.
  • • New caps_triggered array and dominant_cap field on every response — every scoring cap that fired, plus the single tightest one, so you can see WHY a score is low, not just that it is.
  • • Fixed: rugged, jup_verified, deployer_address, insider_holder_count, and the maturity/market-health/rugged capped booleans were computed since v1.4 but never actually returned by the main, batch, or x402 endpoints — now present on all of them.
v1.102026-08-05
  • • honeypot_risk and lp_locked now return real values from RugCheck instead of always null — honeypot_risk is a boolean, lp_locked is { locked, percent }. null still means "could not be checked", never a false-clean default.
v1.92026-08-03
  • • Added webhook subscriptions — POST /api/v1/webhooks/subscribe to get pushed a callback when a mint's safety_score crosses a threshold (above/below), instead of polling.
  • • Edge-triggered delivery (fires once per crossing, not repeatedly), HMAC-signed payloads, DELETE /api/v1/webhooks/{id} to unsubscribe.
v1.82026-07-27
  • • Added GET /api/v1/token-risk/x402 — pay-per-call access via the x402 protocol (USDC on Solana), no API key required. Same price as the existing pay-per-call rate.
  • • Published as an x402-discoverable resource on x402scan.com, with an OpenAPI x-payment-info schema for automated agent discovery.
v1.72026-07-26
  • • Published as an MCP server on Smithery.ai and Glama.ai, alongside the Official MCP Registry — usable directly as a tool by Claude, Cursor, and other MCP-compatible agents.
  • • Published npm plugins for ElizaOS (eliza-plugin-tnt-risk-api) and Solana Agent Kit (solana-agent-kit-plugin-risk-api).
v1.62026-07-25
  • • Published to the Official MCP Registry, mcp.so, RapidAPI, and the Postman Public API Network — more ways to discover and integrate the API.
v1.52026-07-23
  • • Published a ready-to-import Postman collection.
v1.42026-07-21
  • • Published a formal OpenAPI 3.0 spec at /openapi.json.
  • • Rebalanced upstream timeout budget for very large/liquid mints, further reducing false holder_distribution failures.
v1.32026-07-19
  • • Billing security hardening against invoice/payment-matching abuse — no response schema change.
v1.22026-07-18
  • • Fixed timeouts on upstream calls that could occasionally return a raw 502 on slower, less-major tokens.
  • • Fixed holder_distribution occasionally reporting holder_count: 0 on high-volume tokens due to a swallowed RPC failure.
  • • Fixed implausible price_change_24h_percent values passed through from upstream market data.
v1.12026-07-18
  • • Added X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers, later joined by X-Credit-Balance-Usd.
v1.02026-07-18
  • • Public launch: GET /api/v1/token-risk — safety_score, insider_clusters, mint/freeze authority, holder_distribution, market data.
  • • API-key auth, free tier + pay-per-call + subscription billing via Solana Pay.

No mailing list or webhooks yet for update announcements — this page and the X / Telegram links in the footer are the way to stay current.

Limits & pricing

FREE
15 req/day
  • Full response schema
  • Insider-cluster detection
  • No credit card
PAY-PER-CALL
$0.02/call
  • Top up any amount $5–$500
  • Only charged past the free 15/day
  • Subscribers pay $0.015/call for overage beyond their quota
SUBSCRIPTION
$45/30 days
  • 5000 calls included
  • $0.015/call overage after that
  • Manual renewal — no auto-charge
X402 (PAY PER CALL, NO KEY)
$0.02/call
  • No API key, no signup — pay per request
  • USDC on Solana, settled per call via the x402 protocol
  • Built for autonomous agents that pay their own way

Paid in $MRDT / SOL / USDC via Solana Pay — same payment flow as the rest of TNT House. Solana Pay can't auto-charge, so the subscription is a manual 30-day top-up, not a recurring subscription in the traditional sense.

GET /api/v1/token-risk/x402
x402 protocol

x402 turns a 402 Payment Required into a working payment flow: call the endpoint with no auth, get a signed payment challenge back, pay it, retry with the receipt.

  1. GET the endpoint with a mint — no Authorization header needed.
  2. You get back HTTP 402 with a PAYMENT-REQUIRED header — a signed challenge for $0.02 in USDC on Solana.
  3. Sign and settle the payment with any x402-compatible client (or wallet/agent SDK), then retry the same request with an X-PAYMENT header carrying the signed payment.
curl "https://tnt-audit.com/api/v1/token-risk/x402?mint=<MINT_ADDRESS>"
# -> 402 Payment Required, PAYMENT-REQUIRED header has the challenge

# sign + pay with an x402-compatible client, then retry with:
curl "https://tnt-audit.com/api/v1/token-risk/x402?mint=<MINT_ADDRESS>" \
  -H "X-PAYMENT: <base64 signed payment>"
Python (bot/agent client, handles the 402 flow automatically)
pip install openlibx402-client solders

from openlibx402_client import X402AutoClient
from solders.keypair import Keypair
import base58, os

# Load your Solana wallet's private key from an env var -- never hardcode it.
# The wallet needs a small USDC balance on Solana mainnet ($0.02+ per call).
private_key = base58.b58decode(os.environ["SOLANA_PRIVATE_KEY_B58"])
keypair = Keypair.from_bytes(private_key)

# X402AutoClient handles the whole 402 -> pay -> retry flow automatically --
# this one call does everything the curl example above does by hand.
client = X402AutoClient(wallet_keypair=keypair)
response = await client.fetch(
    "https://tnt-audit.com/api/v1/token-risk/x402?mint=<MINT_ADDRESS>"
)
data = response.json()
print(data["safety_score"], data["insider_clusters"])

Same $0.02/call rate as the standard pay-per-call tier, but no account or stored key needed — for agents that would rather settle per-request than hold a key. Listed on x402scan.com.

Manage billing →