WalletDNA

API Reference

Screen and analyze any crypto wallet programmatically, with signed webhooks for continuous re-screening. Available on the Advanced and Enterprise plans. OpenAPI spec ↗

Authentication

Pass your API key in one of two ways:

# Header (recommended)
X-Api-Key: wdna_your_key_here

# Or as a Bearer token
Authorization: Bearer wdna_your_key_here

Generate keys in Developer → API Keys. Keys are shown only once — store them securely.

Base URL

https://walletdna.com

Endpoints

POST/api/v1/screenScreen wallets → allow / review / block

The screening primitive: pass one address, or up to 25 in addresses, and get a decision your policy engine, Travel-Rule flow, or KYT step can act on. Optional thresholds map the risk score to review/block (sanctioned hits always block). Each address counts as one call.

Request

curl -X POST https://walletdna.com/api/v1/screen \
  -H "X-Api-Key: wdna_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "0x722122dF12D4e14e13Ac3b6895a86e84145b6967",
    "thresholds": { "review": 50, "block": 80 }
  }'

Response

{
  "result": {
    "address":   "0x722122dF12D4e14e13Ac3b6895a86e84145b6967",
    "chain":     "ETH",
    "riskScore": 96,
    "riskLabel": "CRITICAL",
    "decision":  "block",
    "sanctioned": { "hit": true, "authorities": ["OFAC"] },
    "category":  "sanctioned",
    "entity":    { "name": "Tornado Cash", "type": "Threat Actor" },
    "screenedAt": "2026-06-22T18:30:00.000Z"
  },
  "thresholds": { "review": 50, "block": 80 }
}

Batch: send {"addresses": ["0x…", "0x…"]} (max 25) → { "results": [...], "count": n }.

POST/api/analyzeFull analysis of a single wallet

Request

curl -X POST https://walletdna.com/api/analyze \
  -H "X-Api-Key: wdna_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"wallet": "1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf6Y"}'

Response

{
  "wallet":     "1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf6Y",
  "chain":      "BTC",
  "balance":    "72.31337 BTC",
  "confidence": "verified",
  "entity": {
    "name":   "Satoshi Genesis Block",
    "type":   "Exchange",
    "source": "walletdna-verified"
  },
  "tags": [
    "Chain: BTC",
    "Veteran wallet (since 2009)",
    "Whale (72 BTC)"
  ],
  "riskScore": {
    "score":   12,
    "label":   "LOW",
    "color":   "#22c55e",
    "factors": ["No risk signals detected"],
    "breakdown": [...]
  },
  "analysisId": "uuid",
  "evidence":   [...],
  "summary":    "Unique DNA found for 1A1zP1…"
}
POST/api/analyze/batchAnalyze up to 20 wallets at once — Advanced & Enterprise

Request

curl -X POST https://walletdna.com/api/analyze/batch \
  -H "X-Api-Key: wdna_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "wallets": [
      "1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf6Y",
      "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
    ]
  }'

Response

{
  "results": [
    { "wallet": "1A1z...", "chain": "BTC", ... },
    { "wallet": "0xd8...", "chain": "ETH", ... }
  ],
  "count": 2
}

Webhooks — continuous re-screening

Register HTTPS endpoints in Developer → Webhooks. Any wallet you monitor is re-screened daily; when its risk crosses into high/critical or it lands on a sanctions list, WalletDNA POSTs a signed event so the change flows into your stack — you're not a one-time check, you're always on.

Event types

wallet.risk_changed · wallet.sanctioned · wallet.tainted_source

Payload

POST https://your-endpoint.example.com
WalletDNA-Event: wallet.sanctioned
WalletDNA-Signature: t=1750617000,v1=4f8c…hexhmac

{
  "id":   "evt_3f8c1d2e9a7b4c5d6e7f8a9b",
  "type": "wallet.sanctioned",
  "created": 1750617000,
  "data": {
    "address":   "0x722122dF…6967",
    "chain":     "ETH",
    "riskScore": 96,
    "decision":  "block",
    "sanctioned": { "hit": true, "authorities": ["OFAC"] },
    "previousScore": 41,
    "monitorId": "uuid",
    "reportUrl": "https://walletdna.com/report/uuid"
  }
}

Verify the signature

Recompute the HMAC over ${t}.${rawBody} with your endpoint secret (whsec_…) and compare to v1:

import crypto from "crypto";

function verify(rawBody, header, secret) {
  const [t, v1] = header.split(",").map(p => p.split("=")[1]);
  const expected = crypto.createHmac("sha256", secret)
    .update(`${t}.${rawBody}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Return any 2xx to acknowledge. Reject if the timestamp is older than ~5 minutes to prevent replay.

Errors

StatusCodeMeaning
401UnauthorizedMissing or invalid API key
403ForbiddenPlan doesn't include this endpoint
429rate_limitedMonthly call limit reached
400Bad RequestMissing or invalid wallet address

Rate Limits

PlanCalls / monthBatch
Advanced10,000Yes (25 per request)
EnterpriseUnlimitedYes (25 per request)

Supported Chains

Chain is auto-detected from the address format. Supported: BTC, ETH, SOL, XRP, TRX, BNB, MATIC, LTC, ADA, DOT, AVAX, ATOM, XLM, BASE, ARB, OP, TON, SUI.

MCP Server — for AI agents

Drive WalletDNA from MCP-compatible clients (Claude Desktop, Cursor, agents). The server (in mcp/ in the repo) exposes analyze_wallet, trace_funds, and screen_wallets as tools.

{
  "mcpServers": {
    "walletdna": {
      "command": "node",
      "args": ["/path/to/walletdna/mcp/walletdna-mcp.mjs"],
      "env": { "WALLETDNA_API_KEY": "wdna_your_key_here" }
    }
  }
}

Run npm install in mcp/ first. trace_funds works without a key.

SDKs

Dependency-free official clients wrap screening, batch screening, webhook management, and HMAC signature verification. Source lives in sdks/ in the repo.

JavaScript / TypeScript

import { WalletDNA } from "walletdna-sdk";

const wdna = new WalletDNA(process.env.WALLETDNA_API_KEY);
const { decision } = await wdna.screen("0x722122dF12D4e14e13Ac3b6895a86e84145b6967");
if (decision === "block") rejectDeposit();

Python

from walletdna import WalletDNA

wdna = WalletDNA(os.environ["WALLETDNA_API_KEY"])
verdict = wdna.screen("0x722122dF12D4e14e13Ac3b6895a86e84145b6967")
if verdict["decision"] == "block":
    reject_deposit()

No-code — Zapier & Make

Connect screening and webhook events to 7,000+ apps without writing code.

Zapier

The Zapier app (in integrations/zapier/) ships a Screen Wallet action and a Wallet Risk or Sanctions Change trigger. Authenticate with your wdna_… key, then build Zaps like: new row in Sheets → Screen Wallet → if block, alert Slack.

Make (HTTP + Webhooks)

No dedicated app needed — use Make's built-in modules:

Verify the WalletDNA-Signature header on received events (see the Webhooks section). The SDKs do this for you.

Ready to integrate?
Generate your API key in Developer.
Get API key ↗