Classify Addresses In Bulk
Use address summaries and address intelligence for ordered, indexed wallet and contract classification.
Classify addresses in bulk
Use this guide when you already have a bounded list of wallets or contracts and need one request to answer:
- is this address deployed?
- is it likely an account or contract?
- what class hash or deployment evidence is indexed?
- does Starkscan have a readable label or protocol attribution?
- has the address ever received indexed token transfers?
- when was the latest indexed activity?
These routes are designed for wallet, paymaster, migration, and account-intelligence backends. They use indexed read models only. They do not call Starknet RPC, run deployment repair, scan raw activity, run sanctions/risk screening, or perform heuristic mixer-proximity analysis on the request path.
Pick the light or rich route
| Route | Use when | Adds |
|---|---|---|
POST /v1/{chain}/address/summaries | you need ordered aggregate address facts for navigation, hydration, or preflight checks | activity count, latest activity, class hash, account hint, deployment tx/deployer when indexed |
POST /v1/{chain}/address/intelligence | you also need classification fields for wallet, paymaster, or migration backends | label, protocol, deployed flag, inbound-funds flag, provenance source |
Both routes are advanced-utility routes and require a utility or batch-scope API key. Standard read keys can return 403 on these batch helpers.
Contract
- Body key is
addresses. - Maximum batch size is 128 addresses.
- Results preserve the request order after validation.
- Duplicate addresses are rejected by the SDK helpers before a request is sent.
- The API validates Starknet felt-style
0xaddresses and returns400for malformed input. 429means the route-class budget is exhausted; honorRetry-After.503means a bounded serving query timed out; honorRetry-Afterwhen present. These batch timeout responses currently useRetry-After: 2.
HTTP
export STARKSCAN_API_KEY="YOUR_STARKSCAN_API_KEY"
export STARKSCAN_CHAIN="${STARKSCAN_CHAIN:-SN_MAIN}"
STARKSCAN_BASE_URL="${STARKSCAN_BASE_URL:-https://api.starkscan.co}"
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Starkscan-Api-Key: $STARKSCAN_API_KEY" \
-d '{"addresses":["0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a","0x259fec57cd26d27385cd8948d3693bbf26bed68ad54d7bdd1fdb901774ff0e8"]}' \
"$STARKSCAN_BASE_URL/v1/$STARKSCAN_CHAIN/address/intelligence"TypeScript SDK
import { createStarkscanClient } from '@starkscan/sdk';
const starkscan = createStarkscanClient({
apiKey: process.env.STARKSCAN_API_KEY,
chainId: process.env.STARKSCAN_CHAIN || 'SN_MAIN',
});
const addresses = [
'0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a',
'0x259fec57cd26d27385cd8948d3693bbf26bed68ad54d7bdd1fdb901774ff0e8',
];
const intelligence = await starkscan.addressIntelligence(addresses);
for (const item of intelligence.items) {
console.log({
address: item.address,
label: item.label,
labelSource: item.labelSource,
typeLabel: item.typeLabel,
typeLabelSource: item.typeLabelSource,
protocol: item.protocol?.name ?? null,
isDeployed: item.isDeployed,
classHash: item.classHash,
classLabel: item.classLabel,
classLabelSource: item.classLabelSource,
hasReceivedFunds: item.hasReceivedFunds,
latestActivityBlock: item.latestActivityBlock,
source: item.source,
});
}CLI
starkscan --output-format json address-intelligence \
0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a \
0x259fec57cd26d27385cd8948d3693bbf26bed68ad54d7bdd1fdb901774ff0e8For larger local lists, put one address per line. Blank lines and lines starting with # are ignored before validation:
starkscan --output-format json address-intelligence --file addresses.txtUse address-summaries when you want the lighter aggregate view:
starkscan --output-format json address-summaries \
0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a \
0x259fec57cd26d27385cd8948d3693bbf26bed68ad54d7bdd1fdb901774ff0e8Field semantics
| Field | Meaning |
|---|---|
isDeployed | Starkscan has indexed deployment or class evidence for the address. |
classHash | Indexed deployment/read-model class hash when deployment/class metadata is available. It may not be the current runtime class after account or contract upgrades; use RPC starknet_getClassHashAt when current class state matters. |
classLabel | Nullable class-family label when classHash matches a reviewed official class registry, such as an account or standard-contract family. This is separate from label and is not a curated address name tag. |
classLabelSource | Provenance for classLabel, currently official_class_registry or null. |
isAccount | Best indexed account-contract hint. null means unknown, not false. |
deployedAtTxHash / deployedByAddress | Deployment provenance when indexed. null means Starkscan does not have that provenance in the serving table. |
label / protocol | Nullable curated or indexed attribution hints for display and routing. Coverage is partial. |
labelSource | Provenance for label, such as indexed_protocol_registry, indexed_token_metadata, or curated_known_token_metadata. null means no label was resolved. |
typeLabel | Nullable account/contract type label such as Account contract or Contract, derived from indexed account-kind evidence. This is not a curated name tag. |
typeLabelSource | Provenance for typeLabel, currently indexed_account_kind or null. |
hasReceivedFunds | The address appears as a recipient in indexed token-transfer rows. It is not a balance check. |
latestActivityBlock | Highest indexed activity block for the address when any activity exists. |
totalActivityCount / activityCountExact | Aggregate activity count plus an explicit exactness flag. If activityCountExact=false, treat the count as inexact batch metadata. |
source | Machine-readable provenance for the classification item, separate from labelSource. |
Data honesty rules
- Use
nullas unknown. Do not convert it to false. - Do not treat missing labels as proof that an address is not a protocol or contract.
- Do not treat account type/template labels as equivalent to curated entity names; class-hash labels, when present, must be stored separately from counterparty
labelprovenance. - Do not treat
hasReceivedFunds=falseas proof of zero current balance; use token holdings or exact tokenbalance-ofwhen balances matter. - Do not treat
classLabelas a unique address name. It describes the reviewed class family behind the indexedclassHash, whilelabelremains the curated/token address label. - Do not treat
classHashas a current-state proof after upgrades. It is indexed read-model metadata, not a request-path RPC lookup. - Do not treat this route as compliance screening. It returns factual indexed classification and attribution only, not risk scores, sanctions screening, or mixer-proximity heuristics.
- Keep the original request list so you can join by position as well as by returned address.
Production pattern
- Validate and deduplicate the address list in your backend.
- Keep each batch at or below 128 addresses.
- Call
address/intelligencefor the rich first pass. - Store
source,activityCountExact, and nullable fields so downstream jobs can distinguish unknown from false. - For detailed wallet views, follow up with
address/{address}/activity,address/{address}/transactions, or token holdings on only the addresses a user opens.
For a complete multi-wallet starter across REST, SDK, and CLI, use Monitor 10 wallets.