Quickstart — first verdict in 30 seconds
You'll need an API key. Sign up at app.daoaml.com, copy the key from settings → keys, and:
# 1. Install the CLI (npm, brew, scoop, or curl) $ npm i -g @daoaml/cli # 2. Set your key $ export DAOAML_KEY="sk_live_…" # 3. Run a check $ daoaml check 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 → verdict_id: vd_01HZK4M7Q3X9 → score: 5/100 (LOW) → verdict: https://daoaml.com/v/vd_01HZK4M7Q3X9
That's the whole loop. The verdict link is what you forward to a compliance team — it's a public, signed page they can verify on their side.
Authentication
All requests use bearer-token auth. Pass the API key in the Authorization header. Keys are environment-scoped — sk_test_… hits the sandbox, sk_live_… hits production.
API keys
curl https://api.daoaml.com/v1/check \ -H "Authorization: Bearer sk_live_***" \ -H "Content-Type: application/json" \ -d '{"chain":"ethereum","address":"0xd8dA…"}'
Keys never leave the dashboard except as ***. Rotate any time — old key revokes immediately, no grace window.
Rate limits
Limits are per-account, not per-key. Live tier: 240 req/min, with a 30-request burst. Sandbox: 60/min. The response always carries:
X-RateLimit-Limit: 240 X-RateLimit-Remaining: 237 X-RateLimit-Reset: 1714826400
Hit a 429? Back off using the Retry-After seconds. We never charge for rate-limited responses.
REST endpoints
Four endpoints. That's all there is. Base URL: https://api.daoaml.com/v1.
POST /v1/check
Run an AML check on a single address. Returns a verdict in 0.8–2.4s p95. Costs $2.99 per call on the live tier (free in sandbox).
ethereum, bitcoin, tron, solana, … (full list at GET /v1/chains).{
"id": "vd_01HZK4M7Q3X9",
"chain": "ethereum",
"address": "0xd8dA…",
"score": 5,
"badge": "LOW",
"categories": ["individual", "public_figure"],
"exposure": {
"direct": { "sanctions": 0, "mixers": 0 },
"indirect_3hop": { "darknet": 0.0001 }
},
"verdict_url": "https://daoaml.com/v/vd_01…",
"signed_at": "2026-05-04T11:22:43Z",
"signature": "ed25519:7Q3X…"
}
GET /v1/verdict/:id
Retrieve a verdict by its ID. Verdicts are immutable and cached forever — same call returns the same payload byte-for-byte. Free.
$ curl https://api.daoaml.com/v1/verdict/vd_01HZK4M7Q3X9 \ -H "Authorization: Bearer sk_live_***"
POST /v1/check/batch
Submit up to 1,000 addresses in one call. You get back a batch_id. Poll or use a webhook. Volume discount applies (see pricing).
{
"items": [
{ "chain": "ethereum", "address": "0x…" },
{ "chain": "bitcoin", "address": "bc1…" }
],
"webhook_url": "https://your.app/wh/aml"
}
GET /v1/lists
Daily diff of every sanctions list we track — OFAC SDN, EU CFSP, UK OFSI, UN, plus 14 chain-specific darknet/mixer lists. Supports ?since= for delta polling. Free.
Webhooks
Three event types: verdict.completed, verdict.escalated, list.updated. We POST a JSON payload, sign it with HMAC-SHA256, and retry up to 6 times with exponential backoff (1m → 1h).
POST /your/webhook X-DAOAML-Event: verdict.completed X-DAOAML-Signature: t=1714826400,v1=a3f9… { "event": "verdict.completed", "data": { /* full verdict object */ } }
Verify the signature: HMAC-SHA256 over ${'{'}t{'}'}.${'{'}body{'}'} using your webhook secret. Reject anything older than 5 minutes — replay defense.
Command-line interface
The CLI is a thin wrapper over the API, optimized for shell pipelines and one-off checks.
$ daoaml --help USAGE: daoaml <command> [args] COMMANDS: check <chain:address> run a single check batch <file.csv> submit a CSV (chain,address) verdict <id> fetch by id, prints JSON watch <address> poll daily, alert on change lists diff [--since=…] sanctions delta login interactive key setup whoami show current account & tier FLAGS: --json machine-readable output --quiet exit 0/1 only, no stdout --depth=N indirect exposure hops (1..5)
Pipe-friendly. daoaml watch 0x… --quiet && alert is a perfectly valid one-liner.
SDKs
Three first-party SDKs. All thin, all open-source, all type-safe.
Node / TypeScript — @daoaml/sdk
import { Daoaml } from "@daoaml/sdk"; const aml = new Daoaml({ apiKey: process.env.DAOAML_KEY }); const verdict = await aml.check({ chain: "ethereum", address: "0xd8dA…", }); if (verdict.score > 70) await refundAndFreeze(verdict);
Python — daoaml
from daoaml import Daoaml aml = Daoaml(api_key=os.environ["DAOAML_KEY"]) v = aml.check(chain="ethereum", address="0xd8dA…") if v.score > 70: refund_and_freeze(v)
Go — github.com/daoaml/go-sdk
aml := daoaml.New(os.Getenv("DAOAML_KEY")) v, err := aml.Check(ctx, &daoaml.CheckReq{ Chain: "ethereum", Address: "0xd8dA…", }) if err != nil { return err } if v.Score > 70 { return refundAndFreeze(v) }
Error codes
Stable, documented, exhaustive. We don't add new ones without a minor-version bump.
/v1/chains.Retry-After.X-Trace-Id attached.OpenAPI & llms.txt
Two machine-readable surfaces. Either one is enough to wire an agent or generate clients.