Get a wallet's observed Interaction Graph
Returns deduplicated onchain counterparty addresses from Kyro's newest
persisted snapshot for each supported chain. A counterparty can carry a
registered Kyro profile link and a verifiedKyroPeer overlay when the
existing verified Trust Graph also contains that wallet.
Interaction Graph is score-neutral and is not an endorsement. Each
node carries a required, nullable metrics object read from Kyro's
persisted snapshot evidence: transaction count, in/out direction,
first/last interaction and per-currency native value (exact
native-unit decimal strings), with a lowerBound flag and a
per-chain basis reporting how complete the counts are. Nodes whose
snapshots predate stats capture return metrics: null until the
wallet's next refresh; Arc evidence is aggregate-only and never
yields counts. Native value reflects direct native transfers only
(token transfers and contract-internal movements are not counted).
Asset details are not exposed; the capabilities object reports
exactly what is supported. The GET is database-only and never
starts indexing or a provider scan. Coverage status, stale/capped flags
and explanations say when the returned address set is a lower bound.
Results are address-sorted and cursor-paginated by default.
sort=activity opts into an observed-activity ranking: transaction
count, then most recent interaction, then address; metrics: null
nodes trail with rank: null. Ranked reads return a single page
(nextCursor null, no cursor accepted). Ranking is observational
only, never endorsement or trust, and never affects score. Costs 1
rate unit.
Authorization
bearerApiKey Optional Kyro API key: Authorization: Bearer kyro_live_.... Anonymous
access (no header) works on every endpoint with a lower rate limit
(20 units/minute per IP; keyed budgets follow the key's plan, starting
at developer 120). Keys are validated
only when the header is present; a malformed, unknown or revoked key is
rejected with 401 INVALID_KEY.
In: header
Path Parameters
EVM wallet address. 0x + 40 hex characters (case-insensitive).
^0x[a-fA-F0-9]{40}$Query Parameters
Counterparty nodes per page. Defaults to 25 and is capped at 50.
1 <= value <= 5025Opaque cursor returned in interactionGraph.pagination.nextCursor.
Opt-in ranked read. The only accepted value is activity: counterparties
are ordered by observed activity: transaction count (desc), then most
recent interaction (desc), then address (asc). Nodes with metrics: null
follow all measured nodes, address-ascending, and carry rank: null.
Ranked mode returns a single page: pagination.nextCursor is null and
cursor cannot be combined with sort (400, code INVALID_SORT). Any
other value is rejected (400, code INVALID_SORT). Observed activity is
not endorsement or trust and never affects score; when sort is absent
the default enumeration (address-ascending, cursor-paginated) is
unchanged.
Value in
- "activity"
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/interaction-graph/0x1234567890abcdef1234567890abcdef12345678"{ "ok": true, "version": "v1", "data": { "wallet": "0x1234567890abcdef1234567890abcdef12345678", "interactionGraph": { "walletAddress": "0x1234567890abcdef1234567890abcdef12345678", "nodes": [ { "walletAddress": "0xabcdef1234567890abcdef1234567890abcdef12", "username": "amara.kyro", "profileUrl": "/profile/amara.kyro", "registered": true, "verifiedKyroPeer": true, "chains": [ { "chain": "Ethereum Mainnet", "chainId": 1, "explorerUrl": "https://etherscan.io/address/0xabcdef1234567890abcdef1234567890abcdef12" }, { "chain": "Polygon", "chainId": 137, "explorerUrl": "https://polygonscan.com/address/0xabcdef1234567890abcdef1234567890abcdef12" } ], "metrics": { "transactionCount": { "total": 18, "in": 7, "out": 11 }, "firstInteractionAt": "2025-11-03T14:22:09Z", "lastInteractionAt": "2026-08-14T07:51:33Z", "lowerBound": false, "basis": { "counted": 2, "pending": 0, "unavailable": 0 }, "value": [ { "symbol": "ETH", "in": "2.4", "out": "0.85" }, { "symbol": "POL", "in": "0", "out": "312.5" } ] } }, { "walletAddress": "0x9f8e7d6c5b4a39281706f5e4d3c2b1a098765432", "username": null, "profileUrl": null, "registered": false, "verifiedKyroPeer": false, "chains": [ { "chain": "Ethereum Mainnet", "chainId": 1, "explorerUrl": "https://etherscan.io/address/0x9f8e7d6c5b4a39281706f5e4d3c2b1a098765432" } ], "metrics": null } ], "summary": { "totalCounterparties": 2, "returnedCounterparties": 2, "kyroProfilesOnPage": 1, "verifiedKyroPeers": 1, "chainsWithCounterparties": 2 }, "coverage": { "status": "complete", "source": "persisted_snapshot", "observedAt": "2026-08-25T08:41:05Z", "stale": false, "indexing": false, "historyCapped": false, "hasTransientIssues": false, "hasStandingLimitations": false, "chains": [ { "chain": "Ethereum Mainnet", "chainId": 1, "status": "indexed", "counterpartyCount": 2, "indexedAt": "2026-08-25T08:41:05Z", "source": "cached_wallet_intelligence", "historyCapped": false, "recencyReliable": true, "transientIssue": false, "standingLimitation": false }, { "chain": "Polygon", "chainId": 137, "status": "indexed", "counterpartyCount": 1, "indexedAt": "2026-08-25T08:41:05Z", "source": "cached_wallet_intelligence", "historyCapped": false, "recencyReliable": true, "transientIssue": false, "standingLimitation": false } ] }, "pagination": { "limit": 25, "nextCursor": null, "hasMore": false }, "capabilities": { "perCounterpartyTransactionCount": true, "direction": true, "firstInteractionAt": true, "lastInteractionAt": true, "value": true, "assetDetails": false }, "explanations": [ "Some counterparties predate metrics capture; counts appear after this wallet's next refresh." ] } }}