TonWise API

Real-time on-chain security layer for TON. Detect Puppet Masters, Sybil clusters and Unicode spoofs before your users lose money.

<50ms Shield latency
10+ Threats caught/week
7,500+ Graph nodes
24/7 Auto-Hunter
ℹ️ All endpoints require an X-API-Key header. Contact @TonWiseDev to get your key.

Authentication

Pass your API key in the X-API-Key header on every request.

curl
curl https://tonguard.app/api/v1/shield \
  -H "X-API-Key: tw_live_your_key_here" \
  -G -d "contract=EQBHNioK..."

Rate Limits

Shield API responses are Redis-cached. Cache miss triggers live blockchain analysis (~2-5s). Cache hit returns in <50ms.

PlanLimitCache TTL
Free (B2C)10 scans/day per IP24h
ProUnlimited24h
EnterpriseCustom SLAConfigurable
⚠️ Rate limit headers are returned on every response: X-RateLimit-Limit and X-RateLimit-Remaining

Pre-trade Contract Screening

Run a contract through TonWise before a trade executes. Returns risk score, dump probability and sybil cluster count. Cached responses return in under 50ms.

GET /api/v1/shield Fast-lane B2B screening

Query Parameters

ParameterTypeRequiredDescription
contract string required TON contract address (EQ... or 0:...)

Example Request

curl
curl "https://tonguard.app/api/v1/shield?contract=EQBHNioKtx8Fu3pglkxSzvl9zt4KY1ixUl0miMSVCyHvDW60" \
  -H "X-API-Key: tw_live_your_key"

Response

json
{
  "contract":         "EQBHNioKtx8Fu3pglkxSzvl9zt4KY1ixUl0miMSVCyHvDW60",
  "is_safe":          false,
  "dump_probability": 45,
  "reason":           "SYBIL_CONCENTRATION_DETECTED",
  "sybil_clusters":   1
}

Reason Codes

ReasonDescription
CLEANNo threats detected
SYBIL_CONCENTRATION_DETECTEDPuppet Master + Sybil cluster found
DUMP_IMMINENTMicro test-transactions detected, sell incoming
CROSS_CHAIN_EXIT_*Liquidity draining via bridge
INVALID_CONTRACT_OR_NO_HOLDERSContract not found or empty

Address Cluster Intelligence

Map the full scammer cluster around any TON address through the Lazarus graph. BFS-traversal at depth 3 returns linked scams, threat score, cluster membership, and (when available) cross-chain exit history. Where Shield scans one token, Threat Intel maps the network behind it.

Tier: Scale or Enterprise required ($1499+/mo). Pro and Free keys receive HTTP 403 with current_tier field for graceful upgrade prompts.
GET /api/v1/threat-intel/{address} Aggregated graph intel

Path Parameters

ParameterTypeRequiredDescription
address string required TON address. Accepts user-friendly (EQ.../UQ...) or raw (0:hex) format — server canonicalizes on input.

Example Request

curl
curl "https://tonguard.app/api/v1/threat-intel/EQDa4VOnTYlLvDJ0gZjNYm5PXfSmmtL6Vs6A_CZEtXCNICq_" \
  -H "X-API-Key: tw_live_your_scale_key"

Python SDK

python
from tonwise import TonWiseClient, TierError

with TonWiseClient(api_key="tw_live_your_scale_key") as client:
    try:
        intel = client.threat_intel("EQDa4VOnTYlLvDJ0gZjNYm5PXfSmmtL6Vs6A_CZEtXCNICq_")
        print(f"Threat score: {intel.threat_score}/100")
        for scam in intel.linked_scams:
            print(f"  → {scam.contract} ({scam.symbol})")
    except TierError as e:
        print(f"Need Scale tier, you have: {e.current_tier}")

SDK: pip install tonwise (≥ 0.2.0). Both sync (TonWiseClient) and async (AsyncTonWiseClient) variants expose threat_intel(address).

Response (200)

json
{
  "address":                  "0:dae153a74d894bbc32748198cd626e4f5df4a69ad2fa56ce80fc2644b5708d20",
  "threat_score":             40,
  "first_seen":               null,
  "last_activity":            null,
  "associated_addresses":     4999,
  "linked_scams": [
    {
      "contract":    "0:6e6d431b9bafe1...",
      "symbol":      "SYBIL",
      "first_seen":  null,
      "labels":      ["SCAM", "flagged"]
    }
  ],
  "puppet_master_cluster_id": null,
  "labels":                   ["SCAM", "PUPPET_MASTER"],
  "cross_chain_exits":        [],
  "graph_depth":              3,
  "computed_at":              "2026-05-10T12:00:00.000Z"
}

Response Fields

FieldTypeDescription
addressstringCanonical raw form (0:hex), regardless of input format. Echo for client-side cache keying.
threat_scoreint 0-100Nonlinear function of bad-edge density in the cluster. 0 = clean, 100 = saturated with flagged neighbors. Use ≥70 as a hard-block threshold.
associated_addressesintTotal nodes visited in BFS (excluding the queried address). Capped at 5000 for predictable latency.
linked_scams[]arrayTop 20 flagged neighbors, BFS-ordered by proximity (closest first).
linked_scams[].symbol string Threat label (e.g. "SYBIL", "Scam/Risk", "Phishing") — not a jetton symbol. Reflects how the address is classified in the threat graph, sourced from node.label in Lazarus.
labels[]arrayTags on the queried address itself, present only if it's flagged. Common values: "SCAM", "PUPPET_MASTER", "PHISHING".
puppet_master_cluster_idstring?Cluster ID if address belongs to a known Sybil cluster. Currently always null; populated as Lazarus clustering API expands.
cross_chain_exits[]arrayBridge exit history. Currently always empty; populated when KNOWN_INFRASTRUCTURE mapping ships in a future release.
first_seen / last_activitystring?Per-address timestamps. Currently always null; planned for the next graph-layer iteration.
graph_depthintBFS depth used (currently fixed at 3).
computed_atstringISO-8601 UTC timestamp of computation.

Tier Gate Response (403)

Pro or Free keys receive a 403 with the current_tier field — distinguishable from invalid-key 403 (which has no current_tier):

json
{
  "error":        "Threat Intel API requires Scale or Enterprise tier",
  "current_tier": "pro"
}

The Python SDK maps this to tonwise.TierError (subclass of TonWiseError) with .current_tier attribute.

Caching & Latency

Responses cached in Redis for 1 hour with distributed-lock protection against thundering herd on cold cache. Warm latency under 50ms; cold BFS computation typically 60-150ms depending on cluster density. The cluster cap at 5000 visited nodes keeps cold latency predictable for high-traffic addresses.

Shareable Threat Artifacts

Every Auto-Hunter catch is automatically materialized as a public receipt page at tonguard.app/r/{id}. Receipts are pre-rendered with Open Graph and Twitter Card meta tags — any link share (Twitter, Telegram, Discord, Slack, iMessage) surfaces a rich preview with severity badge, threat ID, and key stats.

Free. No API key required. Pages are public and indexable. They exist to make TonWise's value visible whenever a flagged contract gets discussed anywhere on the web.

How Receipts Are Created

The Auto-Hunter monitors new TON liquidity pools and flags scams in real time — Sybil clusters, dump-imminent setups, Unicode-spoof tokens. Each catch triggers two simultaneous actions:

  • A threat report is published to @tonwise_intel Telegram channel.
  • A persistent Receipt row is written to the database with severity, threat ID, sybil count, AI analysis, and a stable 8-hex ID (e.g. r_f698cc17).

The receipt URL is appended to the channel post. Subscribers get a one-tap shareable link; outsiders following the link land on a full threat-detail page.

Receipt Page Anatomy

ElementDescription
Severity badgeCRITICAL / HIGH / MEDIUM / LOW with color-coded border. Severity is floored at MEDIUM for any receipt that came from a publish-gated alert.
Threat IDStable identifier in TW-YYYY-XXXX format. Same contract gets the same ID within a calendar year.
Stats gridDump probability, sybil wallet count, stake controlled (% of supply), and an estimated USD-saved figure (heuristic).
AI AnalysisOne-sentence senior-analyst commentary. Section is hidden when AI generation didn't run for that receipt.
ContractRaw address with Tonviewer deep-link.
Share buttonsPre-filled Twitter intent + "Get TonWise" CTA pointing at the bot.

Embedding in Your Product

Receipt URLs are stable and embeddable. If you operate a TON product (wallet, DEX, mini-app) that wants to surface threat context, you can:

  • Link https://tonguard.app/r/{id} from within your UI for any flagged contract.
  • Trust that Open Graph rendering works on Twitter, Telegram, Discord, Slack, iMessage out of the box.
  • Receipts are not gated by API key — they exist independently of the B2B endpoints.

To map a contract address to its receipt, query the Shield endpoint; if the contract has been flagged, the receipt will exist on its public URL within seconds of the Auto-Hunter catch.

Real-time Event Stream

Register an endpoint and receive signed payloads the moment Auto-Hunter detects a threat. No polling required.

POST /api/v1/webhook/register Register endpoint

Body Parameters

ParameterTypeDescription
url string required HTTPS endpoint to receive events
events string[] optional Event types to subscribe. Default: all
secret string optional HMAC secret. Auto-generated if omitted

Example Request

curl
curl -X POST https://tonguard.app/api/v1/webhook/register \
  -H "X-API-Key: tw_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-bot.com/hook","events":["dump_alert","spoof","sybil_cluster"]}'

Response

json
{
  "webhook_id":  1,
  "url":         "https://your-bot.com/hook",
  "events":      ["dump_alert", "spoof", "sybil_cluster"],
  "secret":      "a3f9b2c1d4e5...",
  "created_at":  "2026-05-02T10:00:00Z",
  "hint":        "Store the secret securely — used to verify HMAC signatures"
}
POST /api/v1/webhook/test Fire test payload
curl
curl -X POST https://tonguard.app/api/v1/webhook/test \
  -H "X-API-Key: tw_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"webhook_id": 1}'
GET /api/v1/webhook/list List registered webhooks
curl
curl https://tonguard.app/api/v1/webhook/list \
  -H "X-API-Key: tw_live_your_key"
DELETE /api/v1/webhook/{webhook_id} Disable webhook
curl
curl -X DELETE https://tonguard.app/api/v1/webhook/1 \
  -H "X-API-Key: tw_live_your_key"

Event Types

dump_alert
Micro test-transactions detected from Puppet Master to Sybils. Coordinated sell typically follows within hours.
sybil_cluster
5+ wallets funded from a single source. Supply artificially concentrated. Manipulation risk elevated.
spoof
Token name contains invisible Unicode characters impersonating USDT, TON or other known assets.
pump_warning
Unusual buy pressure pattern detected. Coordinated accumulation before distribution.

Payload Schema

Every webhook delivery includes the following fields plus an HMAC-SHA256 signature.

json
{
  "event":        "DUMP_ALERT",
  "contract":     "EQBHNioKtx8Fu3pglkxSzvl9zt4KY1ixUl0miMSVCyHvDW60",
  "symbol":       "TVL",
  "sybils":       22,
  "dump_prob":    92,
  "triggered_at": "2026-05-02T10:00:00Z",
  "source":       "tonguard.app",
  "signature":    "sha256=a3f9b2c1..."
}

Request Headers

HeaderValue
X-TonGuard-Signaturesha256=<hmac_hex>
X-TonGuard-EventDUMP_ALERT | SPOOF | SYBIL_CLUSTER
Content-Typeapplication/json

Verify Signature

Always verify the HMAC-SHA256 signature before processing a webhook payload.

python
import hashlib, hmac

def verify(secret: str, payload: bytes, sig_header: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, sig_header)
javascript
const crypto = require('crypto');

function verify(secret, payload, sigHeader) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(sigHeader)
  );
}

Error Codes

StatusCodeDescription
401 Unauthorized Missing or invalid X-API-Key
403 Forbidden API key expired or subscription inactive
429 Rate Limited Daily scan limit reached. Check X-RateLimit-Remaining
503 Upstream Error TONAPI temporarily unavailable. Retry after 30s
💬 Questions or integration issues? Reach out at @TonWiseDev