API

POST /analyze

Analyze a wallet, a program or a token: who it is, how risky it is, the evidence, and its money in and out.

Request

FieldTypeMeaning
addressstringRequired. A base58 Solana address.
depthintegerRecent transactions to read, 1 to 10,000. Default 1,000. Above 1,000 counts as a deep analysis.
request.sh
1curl -X POST https://iriscan.app/api/analyze \2  -H "Authorization: Bearer $IRIS_KEY" \3  -H "Content-Type: application/json" \4  -d '{ "address": "sy88tvipKfaCTuVVeU2PczPa88hqgPfKnYQyCHboHP8", "depth": 5000 }'

Most answers take a few seconds; a 10,000-transaction analysis up to about 20. Allow two minutes before timing out on your side.

Response

200 OK · response.json (abridged)
1{2  "address": "sy88tvipKfaCTuVVeU2PczPa88hqgPfKnYQyCHboHP8",3  "identity": { "type": "MEV_ARBITRAGE", "confidence": 0.95 },4  "risk": { "level": "LOW", "score": 10, "confidence": 0.3 },5  "summary": ["MEV arbitrage bot", "Bot", "Tips Jito", "Swaps on Jupiter"],6  "labels": [],7  "behaviors": [8    {9      "kind": "MEV_ARBITRAGE",10      "title": "MEV arbitrage bot",11      "description": "…",12      "confidence": 0.95,13      "examples": ["5Kq…", "3Ya…"]14    }15  ],16  "behavior": {17    "wallet_age_days": 212,18    "transaction_count": 4100000,19    "transaction_count_exact": false,20    "transactions_analyzed": 1000,21    "unique_counterparties": 38,22    "active": true23  },24  "activity": { "transfers": 41, "swaps": 902, "program_calls": 57 },25  "flows": { "inbound": { … }, "outbound": { … } },26  "meta": {27    "analyzed_at": "2026-09-29T10:12:03Z",28    "data_completeness": 0.9,29    "scope": "live",30    "warning": null,31    "depth": 100032  }33}

Fields

The verdict

FieldTypeMeaning
identity.typestringWhat it is: MEV_ARBITRAGE, EXCHANGE, DRAINER… or UNKNOWN. See Identities.
identity.confidencenumber0 to 1.
risk.level"LOW" | "MEDIUM" | "HIGH"See Risk score.
risk.scorenumber0 to 100.
risk.confidencenumber0 to 1: how sure the level is.
summarystring[]The takeaways, as the report shows them.

Proof

FieldTypeMeaning
labels[]LabelWhat the knowledge base knows: name, category, entity, role, source, source_url, confidence.
behaviors[]BehaviorPatterns found: kind, title, description, confidence, examples (signatures). See Behaviors.
evidence[]EvidenceEvery finding in one list: type (external_label, behavior, counterparty_exposure), description, source, confidence, source_url.
flagged_counterparties[]CounterpartyThreats and sanctions it dealt with: address, label, labels, entity, source, interactions, received_from, sent_to, last_seen.
known_counterparties[]CounterpartyExchanges, protocols and DEXes it dealt with. Same shape.

Activity and money

FieldTypeMeaning
behaviorobjectWallet age in days, transaction_count (estimated unless transaction_count_exact), transactions_analyzed, unique_counterparties, active (a transaction in the last 30 days).
activityobjectHow the analyzed transactions split: transfers, swaps, program calls.
flows.inbound / outboundFlowSideTransfers only: wallets, transactions, sol, usd (stablecoins), other_tokens, and top parties by value, each with lookalike.
connections[]ConnectionEvery counterparty with both directions: sol_in, usd_in, sol_out, usd_out, counts, dust_only, lookalike, and its latest transfers.
swap_venues[]SwapVenueWhere it swapped: program, name, swaps, what was sold and bought, and the recent swaps.
balanceobject | nullWhat it holds now: SOL, its dollar value, tokens and their value.
balance_history[]BalancePointtime, sol, and sampled: true for the early points, false for the exact ones.

Programs and tokens

When the address is a program, program holds its owner, calls and callers. When it is a mint, token holds its launch, trading, actors, holders and rug check, and identity.type is TOKEN.

Meta

FieldTypeMeaning
meta.scope"live" | "database"live: transactions were analyzed. database: only labels were available (not charged); meta.warning says why.
meta.depthnumberThe depth asked for. Fewer are read when the history is shorter.
meta.data_completenessnumber0 to 1: how much of what was needed could be read.
meta.analyzed_atstringISO 8601, UTC.

Using it to screen addresses

A simple policy before paying or accepting funds:

screen.py
1def screen(profile):2    risk = profile["risk"]3    if risk["level"] == "HIGH":4        return "block"5    if risk["level"] == "MEDIUM" or profile["flagged_counterparties"]:6        return "review"7    if profile["meta"]["scope"] != "live":8        return "review"  # labels only: nothing was read9    return "allow"
  • Log the evidence with the decision: it is your record of why.
  • Cache a profile for a while rather than re-analyzing the same address on every payment.