Authentication

All /api/* endpoints and the /ws WebSocket require an API key. Provide it via:

MethodExample
HTTP headerX-API-Key: your-key-here
Query parameter?apiKey=your-key-here

API keys are configured in appsettings.json under the 1F.ApiKeys array, or via the CHAINGRAPH_API_KEYS environment variable (comma-separated).

Note: Static files (index.html, docs.html, etc.) are served without authentication.

Arkham-Compatible Endpoints

Response format mirrors intel.arkm.com/api so existing Arkham users can switch with a URL change.

GET /api/intelligence/address/{address}

Returns intelligence summary for an address: transaction counts, top counterparties, tags, and entity data.

ParameterInDescription
addresspathHex address (0x-prefixed)

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/intelligence/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

Example response

{ "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "addrId": 42781, "chain": "ethereum", "isContract": false, "arkpidia": null, "tags": [], "txCountOut": 1284, "txCountIn": 5732, "txCountTotal": 7016, "topCounterpartiesOut": [ { "address": "0x7a250d...", "txCount": 89 } ], "topCounterpartiesIn": [ { "address": "0xdead...", "txCount": 214 } ] }

GET /api/counterparties/address/{address}?limit=N

Returns the top counterparties for an address, ranked by total transaction count (sent + received).

ParameterInDescription
addresspathHex address (0x-prefixed)
limitqueryMax results (default 25, max 100)

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/counterparties/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045?limit=5

Example response

{ "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "counterparties": [ { "address": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "txsSent": 45, "txsReceived": 12, "txsTotal": 57 } ], "totalCounterparties": 842 }

Search for addresses by hex prefix. Returns up to 20 matching addresses from the index.

ParameterInDescription
queryqueryHex address prefix to search

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/intelligence/search?query=0xd8dA6B

Example response

{ "results": [ "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" ] }

Cross-1F Endpoints

GET /api/graph/neighbors/{address}?direction=out|in|both&limit=N

Returns edges (transactions) for an address. Supports directional filtering and pagination.

ParameterInDescription
addresspathHex address (0x-prefixed)
directionqueryout (default), in, or both
limitqueryMax edges returned (default 100, max 10000)

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/graph/neighbors/0xd8dA6BF2...?direction=both&limit=10

Example response

{ "address": "0xd8dA6BF2...", "direction": "both", "edgeCount": 7016, "edges": [ { "address": "0x7a250d56...", "addrId": 1023, "blockOffset": 18420, "txOffset": 42 } ] }

GET /api/graph/bfs/{address}?hops=3&maxResults=100

Breadth-first search from an address. Discovers all reachable addresses within N hops. Essential for fund tracing and cluster analysis.

ParameterInDescription
addresspathStarting hex address
hopsqueryMax traversal depth (default 3, max 6)
maxResultsqueryMax paths returned (default 100, max 10000)

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/graph/bfs/0xd8dA6BF2...?hops=2&maxResults=50

Example response

{ "address": "0xd8dA6BF2...", "maxHops": 2, "pathCount": 48, "paths": [ { "depth": 1, "path": [ { "from": "0xd8dA6BF2...", "to": "0x7a250d56..." } ] } ] }

GET /api/graph/shortest-path/{from}/{to}?maxHops=5

Find the shortest path between two addresses in the transaction graph. Returns up to 5 shortest paths.

ParameterInDescription
frompathSource hex address
topathDestination hex address
maxHopsqueryMax traversal depth (default 5, max 8)

Example request

curl -H "X-API-Key: YOUR_KEY" \ https://your-host/api/graph/shortest-path/0xd8dA6BF2.../0x7a250d56...?maxHops=4

Example response

{ "from": "0xd8dA6BF2...", "to": "0x7a250d56...", "found": true, "paths": [ { "depth": 2, "path": [ { "from": "0xd8dA...", "to": "0xabcd..." }, { "from": "0xabcd...", "to": "0x7a25..." } ] } ] }

Natural Language Query

POST /api/query

Submit a question in plain English. The LLM translates it into graph query primitives and executes them against the index. Requires a Groq API key to be configured.

Request body

{ "question": "Has this address interacted with Tornado Cash on any chain?" }

Example request

curl -X POST -H "X-API-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"question":"Where did 0xd8dA6BF2... send funds after bridging to Base?"}' \ https://your-host/api/query

Example response

{ "question": "Where did 0xd8dA6BF2... send funds after bridging to Base?", "plan": { "plan": [ { "step": 1, "action": "resolve_address", "params": { "address": "0xd8dA6BF2..." } }, { "step": 2, "action": "neighbors_out", "params": { "addr_id": "$step1.result.addr_id" } } ], "explanation": "Resolve the address, then find all outgoing transactions.", "limitations": "Cannot filter by bridge contract without contract labels." }, "results": [ { "step": 1, "action": "resolve_address", "result": { "addr_id": 42781, "found": true } }, { "step": 2, "action": "neighbors_out", "result": { "count": 1284, "top": [...] } } ] }
Requires LLM: This endpoint needs a Groq API key configured in appsettings.json or via GROQ_API_KEY env var. Returns an error if not configured.

Meta

GET /api/stats

Returns index statistics: total addresses, edges, hash table size, and load status.

Example request

curl -H "X-API-Key: YOUR_KEY" https://your-host/api/stats

Example response

{ "addrCount": 12458203, "edgeCount": 89421547, "tableSize": 16777216, "isLoaded": true, "version": "v6-chaingraph" }

GET /api/chains

Returns the list of supported chains and their ingestion status.

Example request

curl -H "X-API-Key: YOUR_KEY" https://your-host/api/chains

Example response

{ "chains": [ { "id": "ethereum", "name": "Ethereum", "status": "active" }, { "id": "bsc", "name": "BNB Chain", "status": "active" }, { "id": "arbitrum", "name": "Arbitrum", "status": "planned" }, { "id": "base", "name": "Base", "status": "planned" }, { "id": "polygon", "name": "Polygon", "status": "planned" } ] }

WebSocket

ws://host/ws

Binary frame protocol for real-time graph exploration. Used by the Graph Explorer UI.

The WebSocket accepts binary frames where the first byte is the command type:

CommandIDPayload
NEIGHBORS_OUT1uint32 addr_id
NEIGHBORS_IN2uint32 addr_id
BFS3uint32 addr_id + uint8 hops + uint16 maxResults
BLOCK_LOOKUP4uint32 block_offset
ADDR_EXISTS5uint32 addr_id
STATS6(none)

Responses are binary frames. See the Graph Explorer source for parsing details.

Tip: For most use cases, the REST API is simpler. Use WebSocket only when you need sub-millisecond latency for interactive graph exploration.