DEV Community

PublicAML
PublicAML

Posted on Originally published at publicaml.org

KYT vs KYC vs AML for Crypto Developers (With a Free Address Check)

KYT vs KYC vs AML for Crypto Developers (With a Free Address Check)

If you build wallets, OTC desks, NFT checkouts, or DeFi frontends, compliance vocabulary shows up in every roadmap. The acronyms get mashed together. Here is the practical split — and a free way to ship the part users actually feel: screening the destination before send.

KYC — Know Your Customer

Question: Who is using my product?

Typical signals: passport / ID, selfie, proof of address, sanctions name screening.

KYC is identity. It does not tell you whether 0xabc… is a mixer exit or a sanctioned cluster two hops away.

AML — Anti-Money Laundering

Question: Are we preventing illicit finance end-to-end?

AML is the program: policies, monitoring, SAR/STR workflows, travel-rule where required, ongoing review. KYC is one control inside AML. Transaction monitoring and KYT are others.

KYT — Know Your Transaction

Question: Is this payment (or counterparty) risky?

KYT looks at blockchain graph risk: exposure to sanctions, hacks, scams, mixers, darknet, etc. For a non-custodial wallet the highest-ROI check is usually:

Before broadcast, enrich the to address. If risk is high, warn or block.

That is KYT in the product sense — even when the backend labels the field aml_score.

What to implement first (builder priority)

Product First control Why
Non-custodial wallet Destination KYT User still controls keys; you can still stop them sending to a drain
Custodial exchange KYC + deposit/withdraw KYT Regulated perimeter
OTC desk Counterparty KYT + deal notes Speed + court-ready trails
DeFi UI Recipient / router awareness UX warnings before approve/send

Free KYT call you can ship today

PublicAML exposes a public enrich API — no key for the free tier:

const res = await fetch("https://intelapi.publicaml.org/v1/enrich", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    addresses: [
      {
        wallet_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        chain: "ETH",
      },
    ],
  }),
});

const { entities } = await res.json();
const e = entities[0];

console.log({
  score: e.aml_score, // 0–100 KYT-style risk
  label: e.label, // e.g. Bitfinex
  category: e.category, // e.g. cex
});
Enter fullscreen mode Exit fullscreen mode

Use thresholds that match your risk appetite (example: warn ≥ 40, block ≥ 70), and always show label / category so the UX is explainable.

Common mistakes

  1. Treating KYC as KYT — verifying the user does not clear the destination.
  2. Only screening after send — users need the warning before they lose funds.
  3. Score without context — show why (mixer hop, sanction exposure, known CEX).
  4. Paying for keys on day one — prototype with a free endpoint, then graduate if you need SLAs / private datasets.

Bottom line

  • KYC = identity
  • AML = the compliance program
  • KYT = risk of the money path / counterparty

If you only have one engineering sprint, add destination KYT on send. It is the control that stops the most “I sent to a scam address” support tickets — and you can start with a free API at publicaml.org.

Top comments (0)