API guide
Every report on this site comes from a small JSON API. Start a report, poll it, read the result.
How it works
Reports can take from two seconds to a minute, depending on the holder count. The API therefore works in two steps.
POST /api/reportsqueues a report and returns its id at once.GET /api/reports/{id}returns the progress, then the full result when the status isdone.
Each finished report also has a share page at /r/{id}. Sleuth keeps reports for 30 days.
Start a report
Send JSON with a kind and the inputs for that kind.
Token X-Ray
curl -X POST /api/reports \
-H "Content-Type: application/json" \
-d '{"kind":"xray","mint":"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"}'
Overlap scan
curl -X POST /api/reports \
-H "Content-Type: application/json" \
-d '{"kind":"overlap","mints":["MINT_A","MINT_B","MINT_C"],"minMatches":2,"includeExited":false}'
minMatches defaults to the number of mints. includeExited adds wallets that sold but kept the token account open; it is a holder feature once the token gate is live.
Wallet profile
curl -X POST /api/reports \
-H "Content-Type: application/json" \
-d '{"kind":"wallet","address":"WALLET_ADDRESS"}'
Saved scans
A saved scan compares holder lists taken at different times, so a wallet counts even if it sold one coin before the next was called. First save each coin's holders when it is called:
curl -X POST /api/reports \
-H "Content-Type: application/json" \
-d '{"kind":"snapshot","mint":"MINT_A"}'
The finished result holds token, takenAt, holders, complete, a signature sig and list, one [wallet, rawAmount, tag] entry per holder. Keep the whole result. To compare, send each snapshot's header fields with entries set to the list entries whose wallet appears in two or more of your snapshots:
curl -X POST /api/reports \
-H "Content-Type: application/json" \
-d '{"kind":"overlap","minMatches":2,"snapshots":[
{"token":{…},"takenAt":…,"holders":…,"complete":true,"sig":"…","entries":[["WALLET",123,"TAG"]]},
…]}'
Sleuth checks the signature and every tag, and rejects a snapshot with any edited entry. The result is an overlap report with fromSnapshots: true and each token's takenAt.
The response has status 202 and looks like this:
{ "id": "k3VtqZp8fN2a", "kind": "xray", "status": "queued", "progress": 0, "message": "Waiting in line", "tier": "open" }
Read a report
curl /api/reports/k3VtqZp8fN2a
The status moves from queued to running and ends at done or error. Poll every one or two seconds. While the report runs, progress (0 to 1) and message describe the current step. When the status is done, result holds the report. When it is error, error holds a readable reason.
Report fields
X-Ray
token: mint, name, symbol, decimals, supply, token program, mint and freeze authority, Token-2022 extensions, price.holders: counts of wallets, programs and exchange wallets, andcomplete(false when the scan hit its page cap).concentration: top 10, 20 and 50 wallet shares, largest wallet, program and exchange shares, all in percent of supply.flagsandriskLevel: each flag has a level (danger, warning, info, ok), a title and the fact behind it.topHolders: rank, address, amount, percent, funding trace and cluster id.clusters: wallets, shared funders, combined percent and confidence (high or medium).launch: deployer, creation time and platform, dev, bundle, sniper and insider shares (bought and held now), and the early buyers with their funding.gates: the sniper-terminal checks, each with the published rule, this token's value and pass, fail or reported.headline: the single finding that stands out, with a level.deployerHistory,comms(metadata links),market(DexScreener) andcopycats(same-ticker tokens).
Overlap
tokens: the scanned tokens with holder counts.counts: how many wallets match each number of tokens.wallets: up to 500 matching wallets.positionsfollows the order oftokens; an entry is null when the wallet does not hold that token, andexitedis true for a sold position.clustersandwarnings.
Wallet
sol,totalUsd,tokens(largest first) andtokenCount.funding: funder, funder kind (normal, active, busy, program), method, amount, date and signature.activity: recent signature count and the time span it covers.
Limits and errors
Anonymous requests count against the client IP. Signed-in requests count against the wallet. The GET /api/config endpoint lists the current limits for each tier.
Every error response has the shape { "error": "message" }.
Other endpoints
GET /api/health: version, RPC counters and queue depth.GET /api/config: site name, tier limits and the project token mint.GET /api/me: the tier for the current session.GET /api/feed?limit=20: the latest public X-Ray findings, one per token.GET /api/stats: lifetime counters (X-Rays, tokens, wallets traced, clusters, bundled launches).GET /api/project-token: the project token, its market and same-ticker tokens that are not it.