1<!DOCTYPE html> 2<html lang="en"> 3<head> 4<!-- Google tag (gtag.js) -->
vendor: 64 bytes, lines 4-5
4 5<script async src="https://www.googletagmanager.com/gtag/js?id=
5G-ENZMBCKGDK
vendor: 12 bytes, line 5
5"></script>
6<script> 7
vendor: 133 bytes, lines 7-10
7window.dataLayer = window.dataLayer || []; 8 function gtag(){dataLayer.push(arguments);} 9 gtag('js', new Date()); 10 gtag('config', '
10G-ENZMBCKGDK
vendor: 4 bytes, line 10
10');
11</script>
11 12 13<meta charset="UTF-8"> 14<meta name="viewport" content="width=device-width, initial-scale=1.0"> 15<title>DeFade API Documentation â Multi-Chain Token Risk Analysis</title> 16<meta name="description" content="DeFade API â memecoin risk analysis on Solana, Ethereum, Base & Robinhood. Rug detection, insider mapping, smart money. 25 endpoints, free tier."> 17<meta name="robots" content="index, follow"> 18<link rel="canonical" href="https://defade.org/api-docs"> 19<link rel="icon" href="https://defade.org/favicon.ico"> 20<link rel="apple-touch-icon" sizes="192x192" href="https://defade.org/icon-192.png"> 21 22<!-- Open Graph --> 23<meta property="og:type" content="website"> 24<meta property="og:url" content="https://defade.org/api-docs"> 25<meta property="og:title" content="DeFade API â Multi-Chain Token Risk Analysis"> 26<meta property="og:description" content="Rug pull detection, insider network mapping, smart money tracking & 25 endpoints via a fast REST API. Every plan covers every chain. Plans from $29/mo."> 27<meta property="og:image" content="https://defade.org/og-image.jpg?v=5"> 28<meta property="og:image:width" content="1536"> 29<meta property="og:image:height" content="804"> 30<meta property="og:image:type" content="image/jpeg"> 31<meta property="og:site_name" content="DeFade"> 32 33<!-- Twitter Card --> 34<meta name="twitter:card" content="summary_large_image"> 35<meta name="twitter:site" content="@DeFade_"> 36<meta name="twitter:title" content="DeFade API â Multi-Chain Token Risk Analysis"> 37<meta name="twitter:description" content="Rug pull detection, insider network mapping, smart money tracking & 25 endpoints via a fast REST API. Every plan covers every chain. Plans from $29/mo."> 38<meta name="twitter:image" content="https://defade.org/og-image.jpg?v=5"> 39 40<!-- Structured Data -->
41<script type="application/ld+json"> 42{ 43 "@context": "https://schema.org", 44 "@type": "WebAPI", 45 "name": "DeFade API", 46 "description": "Multi-chain memecoin risk analysis API for Solana, Ethereum, Base and Robinhood Chain â rug pull detection, insider network mapping, smart money tracking, and 25 endpoints.", 47 "url": "https://defade.org/api-docs", 48 "documentationUrl": "https://defade.org/api-docs", 49 "provider": { 50 "@type": "Organization", 51 "name": "DeFade Ltd", 52 "url": "https://defade.org", 53 "logo": "https://defade.org/icon-192.png", 54 "sameAs": ["https://x.com/DeFade_", "https://t.me/DeFadeChat"] 55 }, 56 "offers": [ 57 { "@type": "Offer", "name": "Starter", "price": "99", "priceCurrency": "USD" }, 58 { "@type": "Offer", "name": "Pro", "price": "399", "priceCurrency": "USD" }, 59 { "@type": "Offer", "name": "Enterprise", "price": "1999", "priceCurrency": "USD" } 60 ] 61} 62</script>
62 63<link rel="preconnect" href="https://fonts.googleapis.com"> 64<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 65<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@700&family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;1,400&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet"> 66<style> 67*,*::before,*::after{box-sizing:border-box;margin:0;padding:0} 68:root{ 69 --bg-primary:#030308; 70 --bg-secondary:#0d0d16; 71 --bg-tertiary:#12121c; 72 --bg-card:#0d0d16; 73 --border:rgba(255,255,255,0.06); 74 --border-bright:rgba(255,255,255,0.14); 75 --text-primary:#e8eaf0; 76 --text-secondary:#8b90a0; 77 --text-muted:#565b6e; 78 --accent:#00d4ff; 79 --accent-dim:#00c88a; 80 --accent-glow:rgba(0,229,160,.12); 81 --accent-glow-strong:rgba(0,229,160,.25); 82 --red:#ff4d6a; 83 --orange:#ff8c42; 84 --blue:#4d9fff; 85 --purple:#a97dff; 86 --yellow:#ffd04d; 87 --font-body:'Outfit',system-ui,sans-serif; 88 --font-mono:'JetBrains Mono',monospace; 89 --radius:10px; 90 --radius-sm:6px; 91 --sidebar-w:260px; 92} 93html{scroll-behavior:smooth;-webkit-text-size-adjust:100%} 94body{font-family:var(--font-body);background:var(--bg-primary);color:var(--text-primary);line-height:1.6;-webkit-font-smoothing:antialiased;min-height:100vh} 95body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse 80% 50% at 20% 0%,rgba(0,229,160,.05),transparent),radial-gradient(ellipse 60% 40% at 80% 10%,rgba(77,159,255,.03),transparent)} 96a{color:var(--accent);text-decoration:none;transition:color .2s} 97a:hover{color:#33ffc0} 98::selection{background:var(--accent-glow-strong);color:var(--text-primary)} 99code{font-family:var(--font-mono);font-size:.9em} 100@keyframes gradShift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}} 101 102/* ---- TOP NAV ---- */ 103.topnav{position:fixed;top:0;left:0;right:0;z-index:200;height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 24px;background:rgb(3,3,8);border-bottom:1px solid var(--border)} 104.topnav-brand{display:flex;align-items:center;gap:10px;font-weight:700;font-size:20px;letter-spacing:-.03em} 105.topnav-brand img{width:30px;height:30px;border-radius:7px;object-fit:contain;filter:drop-shadow(0 0 10px rgba(0, 212, 255,.2))} 106.topnav-brand .brand-text{font-family:'Chakra Petch',var(--font-body);background:linear-gradient(135deg,#00d4ff 0%,#4d8fff 50%,#a855f7 100%);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;animation:gradShift 8s ease infinite} 107.topnav-links{display:flex;align-items:center;gap:18px;font-size:13px;font-weight:500} 108.topnav-links a{color:var(--text-secondary)} 109.topnav-links a:hover{color:var(--text-primary)} 110.topnav-cta{padding:6px 16px;border-radius:6px;background:var(--accent);color:var(--bg-primary);font-weight:600;font-size:13px;transition:all .2s} 111.topnav-cta:hover{background:#33ffc0;color:var(--bg-primary)} 112.mobile-menu-btn{display:none;background:none;border:none;color:var(--text-secondary);cursor:pointer;padding:4px} 113 114/* ---- SIDEBAR ---- */ 115.sidebar{position:fixed;top:56px;left:0;bottom:0;width:var(--sidebar-w);background:var(--bg-secondary);border-right:1px solid var(--border);overflow-y:auto;padding:20px 0;z-index:100;transition:transform .3s} 116.sidebar-group{margin-bottom:24px} 117.sidebar-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--text-muted);padding:0 20px;margin-bottom:8px} 118.sidebar-link{display:flex;align-items:center;gap:8px;padding:7px 20px;font-size:13px;color:var(--text-secondary);transition:all .15s;cursor:pointer;border-left:2px solid transparent} 119.sidebar-link:hover{color:var(--text-primary);background:rgba(255,255,255,.02)} 120.sidebar-link.active{color:var(--accent);border-left-color:var(--accent);background:var(--accent-glow)} 121.sidebar-link svg{width:14px;height:14px;opacity:.6;flex-shrink:0} 122 123/* ---- MAIN CONTENT ---- */ 124.main{margin-left:var(--sidebar-w);padding:80px 48px 80px;position:relative;z-index:1;max-width:900px} 125.main section{margin-bottom:64px;scroll-margin-top:72px} 126 127/* ---- TYPOGRAPHY ---- */ 128h1{font-size:clamp(28px,4vw,42px);font-weight:700;letter-spacing:-.03em;line-height:1.15;margin-bottom:12px} 129h1 em{font-style:normal;background:linear-gradient(135deg,#00d4ff,#4d8fff,#a855f7);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;animation:gradShift 8s ease infinite} 130h2{font-size:22px;font-weight:600;letter-spacing:-.02em;margin-bottom:8px;display:flex;align-items:center;gap:10px} 131h2 .icon{color:var(--accent);display:inline-flex;align-items:center} 132h2 .icon svg{width:20px;height:20px} 133h3{font-size:16px;font-weight:600;margin:24px 0 10px;color:var(--text-primary)} 134p.sub{font-size:14px;color:var(--text-secondary);margin-bottom:20px;line-height:1.7} 135p.body-text{font-size:14px;color:var(--text-secondary);line-height:1.8;margin-bottom:16px} 136
137/* ---- CARDS ---- */ 138.card{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);padding:24px;margin-bottom:16px} 139.card:hover{border-color:var(--border-bright)} 140.info-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:16px 0} 141.info-item{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:16px} 142.info-item .label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);margin-bottom:4px} 143.info-item .value{font-size:20px;font-weight:700;color:var(--text-primary)} 144.info-item .value span{font-size:12px;font-weight:400;color:var(--text-muted)} 145 146/* ---- CODE BLOCKS ---- */ 147.code-tabs{display:flex;gap:0;margin-bottom:0;border-bottom:1px solid var(--border);background:var(--bg-tertiary);border-radius:var(--radius) var(--radius) 0 0} 148.code-tab{padding:8px 16px;font-size:12px;font-weight:600;color:var(--text-muted);cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;background:none;border-top:none;border-left:none;border-right:none;font-family:var(--font-body)} 149.code-tab:hover{color:var(--text-secondary)} 150.code-tab.active{color:var(--accent);border-bottom-color:var(--accent)} 151.code-block{background:var(--bg-primary);border:1px solid var(--border);border-top:none;border-radius:0 0 var(--radius) var(--radius);padding:18px 20px;font-family:var(--font-mono);font-size:13px;line-height:1.8;overflow-x:auto;position:relative;display:none} 152.code-block.active{display:block} 153.code-block-solo{background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;font-family:var(--font-mono);font-size:13px;line-height:1.8;overflow-x:auto;position:relative} 154.dim{color:var(--text-muted)} 155.str{color:var(--accent)} 156.key-c{color:var(--blue)} 157.comment{color:var(--text-muted);font-style:italic} 158.kw{color:var(--purple)} 159.fn{color:var(--orange)} 160.copy-btn{position:absolute;top:10px;right:10px;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-secondary);font-size:0;padding:6px;cursor:pointer;transition:all .2s;z-index:2;display:flex;align-items:center;justify-content:center} 161.copy-btn:hover{border-color:var(--accent);color:var(--accent)} 162.copy-btn.copied{color:var(--accent);border-color:var(--accent)} 163 164/* ---- ENDPOINTS ---- */
165.endpoint-group{display:flex;flex-direction:column;gap:10px} 166.endpoint{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;transition:border-color .2s} 167/* The nav is position:fixed and 56px tall, so an #ep-⦠jump used to land the 168 card's method/path row underneath it â the sidebar links reach these cards 169 now, and arriving at a header you cannot read is only half a fix. */ 170.endpoint{scroll-margin-top:72px} 171.endpoint:hover{border-color:var(--border-bright)} 172.endpoint-header{display:flex;align-items:center;gap:12px;padding:14px 20px;cursor:pointer;user-select:none;transition:background .15s} 173.endpoint-header:hover{background:rgba(255,255,255,.015)} 174.method-badge{font-family:var(--font-mono);font-size:11px;font-weight:600;padding:4px 10px;border-radius:4px;letter-spacing:.04em;flex-shrink:0} 175.method-get{background:rgba(0,229,160,.1);color:var(--accent);border:1px solid rgba(0,229,160,.2)} 176.method-post{background:rgba(77,159,255,.1);color:var(--blue);border:1px solid rgba(77,159,255,.2)} 177.endpoint-path{font-family:var(--font-mono);font-size:13px;color:var(--text-primary);font-weight:500} 178.endpoint-path .param{color:var(--orange)} 179.endpoint-desc{font-size:13px;color:var(--text-secondary);margin-left:auto;white-space:nowrap} 180.endpoint-chevron{margin-left:12px;color:var(--text-muted);transition:transform .25s;font-size:12px;flex-shrink:0} 181.endpoint.open .endpoint-chevron{transform:rotate(180deg)} 182.endpoint-detail{display:none;padding:0 20px 20px;border-top:1px solid var(--border)} 183.endpoint.open .endpoint-detail{display:block} 184.detail-section{margin-top:16px} 185.detail-label{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px} 186.detail-desc{font-size:13px;color:var(--text-secondary);line-height:1.7;margin-bottom:12px} 187.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;font-weight:600} 188.tag-free{background:rgba(0,229,160,.1);color:var(--accent)} 189.tag-paid{background:rgba(169,125,255,.1);color:var(--purple)} 190/* Plan badges: the tag names the CHEAPEST plan that unlocks the endpoint, 191 so Starter also covers every Free one and Pro covers all 24. */ 192.tag-starter{background:rgba(0,212,255,.1);color:#00d4ff} 193.tag-pro{background:rgba(169,125,255,.1);color:var(--purple)} 194.tag-chain{background:rgba(255,255,255,.06);color:var(--text-muted);font-weight:500} 195 196/* ---- TABLES ---- */ 197.param-table{width:100%;border-collapse:collapse;font-size:13px;min-width:540px} 198.param-table th{text-align:left;font-weight:500;color:var(--text-muted);padding:6px 12px;font-size:11px;text-transform:uppercase;letter-spacing:.06em} 199.param-table td{padding:8px 12px;border-top:1px solid var(--border);color:var(--text-secondary)} 200.param-table .param-name{font-family:var(--font-mono);color:var(--text-primary);font-weight:500} 201.param-table .param-type{font-family:var(--font-mono);color:var(--purple);font-size:12px} 202.param-table .required{color:var(--red);font-size:11px;font-weight:600} 203 204.field-table{width:100%;border-collapse:collapse;font-size:12px;min-width:540px} 205.field-table th{text-align:left;font-weight:600;color:var(--text-muted);padding:6px 10px;font-size:10px;text-transform:uppercase;letter-spacing:.06em;background:var(--bg-tertiary)} 206.field-table td{padding:7px 10px;border-top:1px solid var(--border);color:var(--text-secondary);vertical-align:top} 207.field-table .fname{font-family:var(--font-mono);color:var(--text-primary);font-weight:500;font-size:12px} 208.field-table .ftype{font-family:var(--font-mono);color:var(--purple);font-size:11px} 209 210.error-table{width:100%;border-collapse:collapse;font-size:13px} 211.error-table th{text-align:left;font-weight:500;color:var(--text-muted);padding:8px 12px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;background:var(--bg-tertiary)} 212.error-table td{padding:10px 12px;border-top:1px solid var(--border);color:var(--text-secondary)} 213.error-table tr:hover td{background:rgba(255,255,255,.01)} 214.status-code{font-family:var(--font-mono);font-weight:600} 215.s4{color:var(--orange)}.s5{color:var(--red)} 216 217/* ---- RESPONSE EXAMPLE ---- */ 218.response-example{background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:14px 18px;font-family:var(--font-mono);font-size:12px;line-height:1.7;overflow-x:auto;max-height:320px;overflow-y:auto;color:var(--text-secondary)} 219.response-example .key-r{color:var(--blue)} 220.response-example .val-s{color:var(--accent)} 221.response-example .val-n{color:var(--orange)} 222.response-example .val-b{color:var(--purple)} 223 224/* ---- PRICING ---- */ 225.pricing-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px} 226.price-card{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);padding:24px 20px;display:flex;flex-direction:column;gap:10px;transition:border-color .2s,transform .2s;position:relative} 227.price-card:hover{border-color:var(--border-bright);transform:translateY(-2px)} 228.price-card.featured{border-color:rgba(0,229,160,.3);background:linear-gradient(to bottom,rgba(0,229,160,.04),var(--bg-secondary))} 229.price-card.featured::before{content:'Popular';position:absolute;top:-10px;right:16px;background:linear-gradient(135deg,#00d4ff,#4d8fff);color:var(--bg-primary);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;padding:3px 10px;border-radius:100px} 230.price-tier{font-size:13px;font-weight:600;color:var(--text-secondary)} 231.price-amount{font-size:32px;font-weight:700;letter-spacing:-.03em;line-height:1} 232.price-amount span{font-size:13px;font-weight:400;color:var(--text-muted)} 233.price-features{list-style:none;display:flex;flex-direction:column;gap:6px;margin-top:4px} 234.price-features li{font-size:12px;color:var(--text-secondary);display:flex;align-items:center;gap:8px} 235.price-features li::before{content:'';width:4px;height:4px;border-radius:50%;background:var(--accent);flex-shrink:0} 236.price-btn{display:block;margin-top:auto;padding:10px 0;width:100%;background:var(--accent);color:var(--bg-primary);border:none;border-radius:8px;font-family:var(--font-body);font-size:13px;font-weight:700;cursor:pointer;transition:all .2s;text-align:center;text-decoration:none} 237.price-btn:hover{opacity:.85;color:var(--bg-primary)} 238.price-btn:disabled{opacity:.5;cursor:wait} 239.price-btn-secondary{background:rgba(255,255,255,.08);color:var(--text-primary);border:1px solid var(--border-bright)} 240.price-btn-secondary:hover{background:rgba(255,255,255,.12);color:var(--text-primary)} 241.price-btn-crypto{margin-top:8px;background:transparent;color:var(--accent);border:1px solid var(--accent)} 242.price-btn-crypto:hover{background:rgba(0,229,160,.1);color:var(--accent)} 243 244/* ---- RATE LIMIT ---- */ 245.rl-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px} 246.rl-item{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius-sm);padding:14px 18px} 247.rl-header-name{font-family:var(--font-mono);font-size:13px;color:var(--blue);font-weight:500} 248.rl-desc{font-size:13px;color:var(--text-secondary);margin-top:4px} 249 250/* ---- CALLOUT ---- */ 251.callout{border-radius:var(--radius-sm);padding:14px 18px;font-size:13px;line-height:1.7;margin:16px 0;display:flex;gap:10px;align-items:flex-start} 252.callout svg{flex-shrink:0;margin-top:2px} 253.callout-info{background:rgba(77,159,255,.06);border:1px solid rgba(77,159,255,.15);color:var(--text-secondary)} 254.callout-warn{background:rgba(255,140,66,.06);border:1px solid rgba(255,140,66,.15);color:var(--text-secondary)} 255.callout-tip{background:rgba(0,229,160,.06);border:1px solid rgba(0,229,160,.15);color:var(--text-secondary)} 256.callout strong{color:var(--text-primary)} 257 258/* ---- FOOTER ---- */ 259.footer{margin-left:var(--sidebar-w);padding:32px 48px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;font-size:13px;color:var(--text-muted);flex-wrap:wrap;gap:12px} 260.footer a{color:var(--text-secondary)} 261
262/* ---- SCROLLBAR ---- */ 263::-webkit-scrollbar{width:5px;height:5px} 264::-webkit-scrollbar-track{background:transparent} 265::-webkit-scrollbar-thumb{background:var(--border-bright);border-radius:3px} 266::-webkit-scrollbar-thumb:hover{background:var(--text-muted)} 267 268/* ---- RESPONSIVE ---- */ 269@media(max-width:900px){ 270 .sidebar{transform:translateX(-100%)} 271 .sidebar.open{transform:translateX(0)} 272 .main,.footer{margin-left:0;padding-left:20px;padding-right:20px} 273 .topnav-links .hide-mobile{display:none} 274 /* The bar has to hold the site burger, the brand, the account pill and the 275 CTA inside 375px. When it cannot, js/nav-drawer.js gives up and floats the 276 burger into a corner â which is how it ended up sideways on the right. */ 277 .topnav{padding:0 24px;gap:10px} 278 .topnav-brand{font-size:17px;gap:7px} 279 .topnav-brand img{width:26px;height:26px} 280 .topnav-links{gap:10px} 281 .topnav-cta{padding:6px 11px;font-size:12px;white-space:nowrap} 282 .pricing-grid{grid-template-columns:1fr 1fr} 283 .endpoint-header{flex-wrap:wrap;gap:8px;padding:12px 16px} 284 .endpoint-desc{margin-left:0;order:3;width:100%;white-space:normal} 285 .footer{flex-direction:column;align-items:flex-start;padding-left:20px} 286 .sidebar-overlay{display:none;position:fixed;inset:0;top:56px;background:rgba(0,0,0,.5);z-index:99} 287 .sidebar-overlay.open{display:block} 288} 289@media(max-width:500px){ 290 .pricing-grid{grid-template-columns:1fr} 291 .info-grid{grid-template-columns:1fr} 292 .topnav{padding:0 24px;gap:8px} 293 .topnav-brand{font-size:15px;gap:6px} 294 .topnav-brand img{width:24px;height:24px} 295 .topnav-cta{padding:5px 9px;font-size:11px} 296} 297</style> 298 <link rel="stylesheet" href="/css/auth.css">
299<script src="/js/site-access.js" defer></script>
299 300<!-- Page-to-page navigation: prefetch a static page's HTML when a link is hovered 301 (token and receipt pages are server-rendered, so they are left out), and keep 302 the current page on screen until the next one can paint instead of flashing blank. --> 303<style>@view-transition{navigation:auto}@media (prefers-reduced-motion:reduce){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none}}</style>
304<script type="speculationrules">{"prefetch":[{"where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":"/*\\?*"}},{"not":{"href_matches":"/api/*"}},{"not":{"href_matches":"/token/*"}},{"not":{"href_matches":"/receipt/*"}},{"not":{"href_matches":"/pump-receipt/*"}},{"not":{"href_matches":"/callback/*"}},{"not":{"href_matches":"/delete-account"}},{"not":{"selector_matches":"[download], [target=_blank]"}}]},"eagerness":"moderate"}]}</script>
304 305</head> 306<body>
307<script src="/js/nav-drawer.js" defer></script>
vendor: 1 bytes, line 307
307
308<script src="/js/native-page.js"></script>
308 309<style> 310/* Native app: the shared adapter pads .nav/.page-header pages, but this page 311 uses a FIXED 56px .topnav with a fixed .sidebar hung at top:56px â grow the 312 topnav by the status-bar inset and shift the whole frame down with it. */ 313body.is-native:not(.is-android) .topnav, body.fullbleed-top .topnav { 314 height: calc(56px + max(calc(env(safe-area-inset-top) - 12px), 47px)); 315 padding-top: max(calc(env(safe-area-inset-top) - 12px), 47px); 316} 317body.is-native:not(.is-android) .sidebar, body.fullbleed-top .sidebar, 318body.is-native:not(.is-android) .sidebar-overlay, body.fullbleed-top .sidebar-overlay { 319 top: calc(56px + max(calc(env(safe-area-inset-top) - 12px), 47px)); 320} 321body.is-native:not(.is-android) .main, body.fullbleed-top .main { 322 padding-top: calc(80px + max(calc(env(safe-area-inset-top) - 12px), 47px)); 323} 324</style> 325 326<!-- TOP NAV --> 327<nav class="topnav"> 328 <div class="topnav-links"> 329 <a href="https://defade.org/developers" target="_blank" class="topnav-cta">Get API Key</a> 330 <div class="nav-links"></div> 331 </div> 332</nav> 333 334<!-- SIDEBAR --> 335<div class="sidebar-overlay" id="sidebar-overlay"></div> 336<aside class="sidebar" id="sidebar"> 337 <div class="sidebar-group"> 338 <div class="sidebar-label">Getting Started</div> 339 <a class="sidebar-link" href="#overview"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>Overview</a> 340 <a class="sidebar-link" href="#quickstart"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>Quick Start</a> 341 <a class="sidebar-link" href="#auth"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>Authentication</a> 342 <a class="sidebar-link" href="#generate-key"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 11-7.778 7.778 5.5 5.5 0 017.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>Generate API Key</a> 343 </div> 344 <div class="sidebar-group"> 345 <div class="sidebar-label">API Reference</div> 346 <a class="sidebar-link" href="#endpoints"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>Endpoints</a> 347 <a class="sidebar-link" href="#ep-analyze"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>Full Analysis</a> 348 <a class="sidebar-link" href="#ep-rug-score"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>Rug Score</a> 349 <a class="sidebar-link" href="#ep-token-price"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6"/></svg>Token Price</a> 350 <a class="sidebar-link" href="#ep-holders"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>Holders</a> 351 <a class="sidebar-link" id="more-endpoints-link" href="#endpoints" style="padding-left:28px;font-size:12px;color:var(--text-muted)">more endpoints</a> 352 <a class="sidebar-link" href="#chains"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/></svg>Chains</a> 353 </div> 354 <div class="sidebar-group"> 355 <div class="sidebar-label">Guides</div> 356 <a class="sidebar-link" href="#pricing"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 3h12l4 6-10 13L2 9z"/><path d="M2 9h20"/></svg>Pricing & Plans</a> 357 <a class="sidebar-link" href="#overage-credits"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v12M6 12h12"/></svg>Overage Credits</a> 358 <a class="sidebar-link" href="#rate-limits"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>Rate Limits</a> 359 <a class="sidebar-link" href="#errors"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/>
359<line x1="12" y1="17" x2="12.01" y2="17"/></svg>Error Handling</a> 360 <a class="sidebar-link" href="#sdks"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>SDKs & Integration</a> 361 <a class="sidebar-link" href="#mcp"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a3 3 0 00-3 3v1a3 3 0 006 0V5a3 3 0 00-3-3z"/><path d="M12 9v4"/><path d="M5 22v-5a7 7 0 0114 0v5"/></svg>MCP Connector</a> 362 <a class="sidebar-link" href="#changelog"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>Changelog</a> 363 </div> 364</aside> 365 366<!-- MAIN CONTENT --> 367<div class="main"> 368 369 <!-- OVERVIEW --> 370 <section id="overview"> 371 <h1>Token <em>intelligence</em>, one API call away</h1> 372 <p class="body-text">The DeFade API gives developers programmatic access to the same on-chain risk analysis that powers <a href="https://defade.org" target="_blank">defade.org</a>. Analyze any token for rug pull risk, insider networks, bundle manipulation, smart money activity, and more â all via a fast REST API. Every endpoint defaults to Solana; adding <code>?chain=</code> runs the same analysis on Ethereum, Base or Robinhood Chain for keys on an All-Chains plan â see <a href="#chains">Chains</a>.</p> 373 374 <div class="info-grid"> 375 <div class="info-item"><div class="label">Base URL</div><div class="value" style="font-family:var(--font-mono);font-size:14px;color:var(--accent)">api.defade.org</div></div> 376 <div class="info-item"><div class="label">Protocol</div><div class="value" style="font-size:14px">REST / HTTPS</div></div> 377 <div class="info-item"><div class="label">Format</div><div class="value" style="font-size:14px">JSON</div></div> 378 <div class="info-item"><div class="label">Auth</div><div class="value" style="font-size:14px">API Key</div></div> 379 <div class="info-item"><div class="label">Endpoints</div><div class="value">22</div></div> 380 <div class="info-item ios-web-pay"><div class="label">Plans from</div><div class="value" style="font-size:14px">$29/mo</div></div> 381 <div class="info-item"><div class="label">Status</div><div class="value" style="font-size:14px"><a href="/api-status" style="color:var(--accent);text-decoration:none;">Live latency & errors</a></div></div> 382 </div> 383 384 <h3>What can you build?</h3> 385 <p class="body-text">Trading bots that check rug risk before buying. Portfolio dashboards with real-time risk scoring. Telegram/Discord bots for community token screening. Browser extensions that warn users on DEX pages. Analytics platforms tracking insider activity across Solana, Ethereum, Base and Robinhood Chain.</p> 386 </section> 387 388 <!-- QUICK START --> 389 <section id="quickstart"> 390 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg></span> Quick Start</h2> 391 <p class="sub">Make your first API call in under 60 seconds.</p> 392 393 <h3>1. Get an API key</h3> 394 <p class="body-text">Paid plans are self-serve: pick Starter, Pro or Enterprise under <a href="#pricing">Pricing</a> (or at <a href="https://defade.org/developers">defade.org/developers</a>), pay by card or crypto, and your key is shown on the confirmation page and emailed to you straight away. Want to try first? <a href="https://defade.org/developers#keygen">Request a free 7-day trial key</a> and tell us what you're building; we review and email it, usually within 24 hours. Either way, send the key with every request in the <code>x-api-key</code> header. The same key also powers the <a href="#mcp">MCP connector</a> for Claude and ChatGPT.</p> 395 396 <h3>2. Analyze a token</h3> 397 <p class="body-text">Use your key to run a full analysis on any Solana token mint address:</p> 398 399 <div class="code-tabs" id="tabs-qs"> 400 <button class="code-tab active" onclick="switchTab('tabs-qs','qs-curl',this)">cURL</button> 401 <button class="code-tab" onclick="switchTab('tabs-qs','qs-js',this)">JavaScript</button> 402 <button class="code-tab" onclick="switchTab('tabs-qs','qs-py',this)">Python</button> 403 </div> 404 <div class="code-block active" data-group="tabs-qs" id="qs-curl"> 405 <button class="copy-btn" onclick="copyBlock(this,'qs-curl')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 406<pre><span class="dim">
406curl</span> <span class="str">https://api.defade.org/v1/analyze/YOUR_TOKEN_MINT</span> \ 407 <span class="dim">-H</span> <span class="str">"x-api-key: df_your_api_key"</span></pre> 408 </div> 409 <div class="code-block" data-group="tabs-qs" id="qs-js"> 410 <button class="copy-btn" onclick="copyBlock(this,'qs-js')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 411<pre><span class="kw">const</span> <span class="fn">res</span> = <span class="kw">await</span> <span class="fn">fetch</span>(<span class="str">'https://api.defade.org/v1/analyze/YOUR_TOKEN_MINT'</span>, { 412 <span class="key-c">headers</span>: { <span class="str">'x-api-key'</span>: <span class="str">'df_your_api_key'</span> } 413}); 414<span class="kw">const</span> data = <span class="kw">await</span> res.<span class="fn">json</span>(); 415console.<span class="fn">log</span>(data.risk.score, data.risk.rating);</pre> 416 </div> 417 <div class="code-block" data-group="tabs-qs" id="qs-py"> 418 <button class="copy-btn" onclick="copyBlock(this,'qs-py')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 419<pre><span class="kw">import</span> requests 420 421res = requests.<span class="fn">get</span>( 422 <span class="str">'https://api.defade.org/v1/analyze/YOUR_TOKEN_MINT'</span>, 423 <span class="key-c">headers</span>={<span class="str">'x-api-key'</span>: <span class="str">'df_your_api_key'</span>} 424) 425data = res.<span class="fn">json</span>() 426<span class="fn">print</span>(data[<span class="str">'risk'</span>][<span class="str">'score'</span>], data[<span class="str">'risk'</span>][<span class="str">'rating'</span>])</pre> 427 </div> 428 429 <h3>3. Interpret the results</h3> 430 <p class="body-text"><strong>Two endpoints score a token, on scales that run in OPPOSITE directions.</strong> Read this before wiring either into a threshold: <code style="color:var(--orange)">rugScore</code> counts UP toward danger, while <code style="color:var(--orange)">risk.score</code> counts DOWN toward it. A token scoring 85 is near-certain trouble on one and near-clean on the other.</p> 431 432 <h4 style="margin:20px 0 8px">/v1/rug-score — <code style="color:var(--orange)">rugScore</code>
432, 0 safe → 100 critical</h4> 433 <p class="body-text">The rug probability model. Higher is worse. <code>verdict</code> is the label, <code>verdictColor</code> the colour to render it in.</p> 434 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm)"> 435 <table class="field-table"> 436 <thead><tr><th>rugScore</th><th>verdict</th><th>verdictColor</th><th>Interpretation</th></tr></thead> 437 <tbody> 438 <tr><td class="fname">0–24</td><td style="color:var(--accent-dim);font-weight:600">PROBABLY SAFE</td><td class="fname" style="color:var(--text-muted)">green</td><td>Minimal risk indicators. Liquidity and holder distribution look healthy, no major flags.</td></tr> 439 <tr><td class="fname">25–44</td><td style="color:var(--yellow);font-weight:600">SOME RISK</td><td class="fname" style="color:var(--text-muted)">yellow</td><td>A few risk factors present. Review the detailed analysis before trading.</td></tr> 440 <tr><td class="fname">45–59</td><td style="color:var(--orange);font-weight:600">ELEVATED RISK</td><td class="fname" style="color:var(--text-muted)">orange</td><td>Several signals stacking up. This is the band at which a token is auto-recorded to the rug database.</td></tr> 441 <tr><td class="fname">60–74</td><td style="color:var(--red);font-weight:600">HIGH RISK</td><td class="fname" style="color:var(--text-muted)">red</td><td>Significant risk signals: bundled wallets, concentrated holdings, or suspicious dev activity.</td></tr> 442 <tr><td class="fname">75–100</td><td style="color:var(--red);font-weight:600">EXTREME RISK</td><td class="fname" style="color:var(--text-muted)">red</td><td>Strong rug pull indicators. The coordinated-supply kill switch floors the score here.</td></tr> 443 </tbody> 444 </table> 445 <p class="body-text" style="margin-top:12px">Tokens that have already collapsed override the bands entirely and return <code>RUGGED / DEAD</code> or <code>ABANDONED / DEAD</code>, signalling liquidity or activity has effectively gone to zero. A launchpad coin that never left its bonding curve returns <code>NEVER BONDED</code> instead: no pool ever existed, so nothing could be pulled. <code>rugScore</code> is still a number in every case; <code>scoreLabel</code> is <code>"NEVER BONDED"</code>
445 when DeFade's own surfaces print the state in place of the percentage, and <code>null</code> otherwise.</p> 446 </div> 447 448 <h4 style="margin:24px 0 8px">/v1/analyze — <code style="color:var(--orange)">risk.score</code>, 100 safe → 0 critical</h4> 449 <p class="body-text">The legacy safety score, carried on the <code>risk</code> object as <code>score</code>, <code>rating</code>, <code>color</code> and <code>flags</code>. <strong>Higher is safer</strong> — the inverse of rugScore, and a different set of labels. If you only need one number, use /v1/rug-score.</p> 450 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm)"> 451 <table class="field-table"> 452 <thead><tr><th>risk.score</th><th>risk.rating</th><th>risk.color</th><th>Interpretation</th></tr></thead> 453 <tbody> 454 <tr><td class="fname">80–100</td><td style="color:var(--accent-dim);font-weight:600">PROBABLY SAFE</td><td class="fname" style="color:var(--text-muted)">green</td><td>No blocking signals found.</td></tr> 455 <tr><td class="fname">70–79</td><td style="color:var(--yellow);font-weight:600">PROCEED WITH CAUTION</td><td class="fname" style="color:var(--text-muted)">yellow</td><td>Minor flags worth reading before acting.</td></tr> 456 <tr><td class="fname">60–69</td><td style="color:var(--orange);font-weight:600">ELEVATED RISK</td><td class="fname" style="color:var(--text-muted)">orange</td><td>Real signals present, short of the high-risk bands.</td></tr> 457 <tr><td class="fname">40–59</td><td style="color:var(--orange);font-weight:600">HIGH RISK</td><td class="fname" style="color:var(--text-muted)">orange</td><td>Significant flags across liquidity, holders or the dev wallet.</td></tr> 458 <tr><td class="fname">20–39</td><td style="color:var(--red);font-weight:600">VERY HIGH RISK</td><td class="fname" style="color:var(--text-muted)">red</td><td>Severe, stacked signals.</td></tr> 459 <tr><td class="fname">0–19</td><td style="color:var(--red);font-weight:600">LIKELY RUG</td><td class="fname" style="color:var(--text-muted)">red</td><td>The strongest signals the legacy model has.</td></tr> 460 </tbody> 461 </table> 462 <p class="body-text" style="margin-top:12px">A collapsed token is capped at a score of 15 and rated <code>DEAD / RUGGED</code>, <code>FAILED / ABANDONED</code> or <code>NEVER BONDED</code> (still on its bonding curve) — note these strings differ from the /v1/rug-score overrides above; match on both if you consume the two endpoints.</p> 463 </div> 464 </section> 465 466 <!-- AUTHENTICATION --> 467 <section id="auth"> 468 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg></span> Authentication</h2> 469 <p class="sub">All API requests require authentication via an API key.</p> 470 471 <p class="body-text">Include your key using either the <code style="color:var(--blue)">x-api-key</code> request header (recommended) or the <code style="color:var(--blue)">api_key</code> query parameter. The header method is preferred as it keeps your key out of server logs and browser history.</p> 472 473 <div class="code-tabs" id="tabs-auth"> 474 <button class="code-tab active" onclick="switchTab('tabs-auth','auth-header',this)">Header (recommended)</button> 475 <button class="code-tab" onclick="switchTab('tabs-auth','auth-query',this)">Query Parameter</button> 476 </div> 477 <div class="code-block active" data-group="tabs-auth" id="auth-header"> 478<pre><span class="dim">curl</span> <span class="str">https://api.defade.org/v1/rug-score/TOKEN_MINT</span> \ 479 <span class="dim">-H</span> <span class="str">"x-api-key: df_your_api_key_here"</span></pre> 480 </div> 481 <div class="code-block" data-group="tabs-auth" id="auth-query"> 482<pre><span class="dim">curl</span> <span class="str">"https://api.defade.org/v1/rug-score/TOKEN_MINT?api_key=df_your_api_key_here"</span></pre> 483 </div> 484 485 <div class="callout callout-warn">
486 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> 487 <div><strong>Keep your API key secret.</strong> Never expose it in client-side code, public repos, or browser requests. For frontend apps, proxy requests through your own backend.</div> 488 </div> 489 </section> 490 491 <!-- GENERATE KEY --> 492 <section id="generate-key"> 493 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 11-7.778 7.778 5.5 5.5 0 017.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg></span> Get an API Key</h2> 494 <p class="sub">Buy a plan and the key is yours immediately, or request a free 7-day trial.</p> 495 496 <p class="body-text"><strong>Paid plans are self-serve.</strong> Choose Starter, Pro or Enterprise under <a href="#pricing">Pricing</a> or on <a href="https://defade.org/developers">defade.org/developers</a> and pay by card (Stripe) or crypto. The key is shown on the confirmation page and emailed to you the moment payment clears; no review, no waiting. Every paid plan covers all four chains and every endpoint; the plans differ on monthly allowance and rate limit.</p> 497 <p class="body-text"><strong>Free trial keys are issued on request.</strong> Submit the form at <a href="https://defade.org/developers#keygen">defade.org/developers#keygen</a> with a short note on what you're building. We review each request and email a 7-day trial key, usually within 24 hours. Trial keys reach six endpoints (<code>analyze</code>, <code>rug-score</code>, <code>token-price</code>, <code>holders</code>, <code>kol</code>, <code>trending</code>) plus <code>usage</code>, on every chain we cover — Solana, Ethereum, Base and Robinhood — at 10 req/min, 100 req/day and 3,000 units/month.</p> 498 <p class="body-text">An API-plan key works everywhere: the REST API from your own code and the <a href="#mcp">MCP connector</a> in Claude or ChatGPT, same plan, same quota. DeFade Pro <em>web</em> subscribers get a different, connector-only key from their dashboard; it reaches the connector's tools, spends the plan's monthly scan allowance, and is not valid on the REST API. See <a href="#mcp">MCP connector â Getting a key</a>.</p> 499 500 <h3>Using your key</h3> 501 <p class="body-text">Send your key with every request in the <code>x-api-key</code> header (or as an <code>api_key</code> query parameter). Every paid plan can call all 25 endpoints on every chain; the plans differ on how many requests a month you get and how fast you may send them. See <a href="#authentication">Authentication</a> for details.</p> 502 503 <div class="callout callout-info"> 504 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--blue)" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> 505 <div><strong>Need higher limits?</strong> Every plan includes all 25 endpoints; Pro and Enterprise raise the monthly allowance and the rate limit. Email <a href="mailto:[email protected]" target="_blank">[email protected]</a>.</div> 506 </div> 507 </section> 508 509 <!-- ENDPOINTS --> 510 <section id="endpoints"> 511 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg></span> API Endpoints</h2> 512 <p class="sub">25 endpoints covering every angle of on-chain risk. Click any endpoint to expand full details, parameters, and response schema. Every paid plan unlocks all 25 endpoints â plans differ on included volume, rate limit and chains. The second badge shows chain support: 21 run on every chain, <code>bundles</code> and <code>fee-fingerprint</code> are Solana-only, and <code>usage</code> reports on your key so it has no chain at all (see <a href="#chains">Chains</a>).</p> 513 <p class="body-text">Every endpoint wraps its result in the same envelope: <code>token</code> (the mint you asked about), <code>timestamp</code> (when the response was assembled) and <code>poweredBy</code>, with the endpoint's own fields in between. Five exceptions: <code>/v1/holder-overlap</code> and <code>/v1/wallet-overlap</code>
513 take several mints so they carry <code>mints</code> instead of <code>token</code>; <code>/v1/wallet-reputation</code> is about a wallet, so it carries <code>wallet</code> (and <code>chain</code>); <code>/v1/trending</code> is not about one token so it has no <code>token</code>; and <code>/v1/usage</code> reports on your key, so it has no envelope at all. On <code>/v1/analyze</code> the endpoint's own <code>token</code> object replaces the envelope's mint string.</p> 514 <div class="endpoint-group" id="endpoint-list"></div> 515 </section> 516 517 <!-- CHAINS --> 518 <section id="chains"> 519 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/></svg></span> Chains</h2> 520 <p class="sub">One endpoint set, four chains. Solana is the default; <code>?chain=</code> selects an EVM chain.</p> 521 522 <p class="body-text">Every endpoint takes an optional <code style="color:var(--blue)">chain</code> query parameter. Omit it and the request is treated as Solana, so existing integrations keep working with no change. Pass it to run the same analysis on an EVM chain â the response shape is identical, only the addresses differ.</p> 523 524 <div class="code-tabs" id="tabs-chains"> 525 <button class="code-tab active" onclick="switchTab('tabs-chains','chain-sol',this)">Solana (default)</button> 526 <button class="code-tab" onclick="switchTab('tabs-chains','chain-evm',this)">EVM chain</button> 527 </div> 528 <div class="code-block active" data-group="tabs-chains" id="chain-sol"> 529<pre><span class="dim">curl</span> <span class="str">https://api.defade.org/v1/rug-score/7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU</span> \ 530 <span class="dim">-H</span> <span class="str">"x-api-key: df_your_api_key_here"</span></pre> 531 </div> 532 <div class="code-block" data-group="tabs-chains" id="chain-evm"> 533<pre><span class="dim">curl</span> <span class="str">"https://api.defade.org/v1/rug-score/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48?chain=base"</span> \ 534 <span class="dim">-H</span> <span class="str">"x-api-key: df_your_api_key_here"</span></pre> 535 </div> 536 537 <h3>Supported chains</h3> 538 <div style="overflow-x:auto"> 539 <table class="param-table"> 540 <thead><tr><th><code>chain</code> value</th><th>Network</th><th>Address format</th></tr></thead> 541 <tbody class="chain-id-rows"> 542 <tr><td class="param-name">ethereum</td><td>Ethereum</td><td><code>0x</code> + 40 hex characters</td></tr> 543 <tr><td class="param-name">base</td><td>Base</td><td><code>0x</code> + 40 hex characters</td></tr> 544 <tr><td class="param-name">robinhood</td><td>Robinhood Chain</td><td><code>0x</code> + 40 hex characters</td></tr> 545 </tbody> 546 </table> 547 </div> 548 <p class="body-text" style="margin-top:10px">Plus <code>solana</code> (base58 mint address), which is the default when <code>chain</code> is omitted. Additional chains are added to this list as they launch â this table is generated from the live chain registry, so it always reflects what the API will actually answer for.</p> 549 550 <h3>Which plans reach which chains</h3> 551 <p class="body-text">Chain access is a property of your <em>plan variant</em>, not of the endpoint. Every plan ships in two variants with an <strong>identical endpoint list</strong>:</p> 552 <div style="overflow-x:auto"> 553 <table class="param-table"> 554 <thead><tr><th>Plan</th><th>Chains</th><th>Endpoints</th></tr></thead> 555 <tbody> 556 <tr><td class="param-name">Starter</td><td>Solana + <span class="chain-name-list">Ethereum, Base, Robinhood Chain</span></td><td>All 23</td></tr> 557 <tr><td class="param-name">Pro</td><td>Solana + <span class="chain-name-list">Ethereum, Base, Robinhood Chain</span></td><td>All 23</td></tr> 558 <tr><td class="param-name">Enterprise</td><td>Solana + <span class="chain-name-list">Ethereum, Base, Robinhood Chain</span></td><td>All 23</td></tr> 559 </tbody> 560 </table> 561 </div> 562 <p class="body-text" style="margin-top:10px">Requesting a <code>chain</code> your plan doesn't cover returns <code>403</code>. Sending a <code>0x</code> address without a <code>chain</code>, or a base58 mint with an EVM <code>chain</code>, returns <code>400</code> â the address format and the chain have to agree.</p> 563 564 <h3>Endpoint coverage on EVM</h3> 565 <p class="body-text">20 of the 25 endpoints run on every chain. Two are Solana-only:</p> 566 <div style="overflow-x:auto"> 567 <table class="param-table"> 568 <thead><tr><th>
568Endpoint</th><th>Why</th></tr></thead> 569 <tbody> 570 <tr><td class="param-name">/v1/bundles/:mint</td><td>EVM bundle analysis is a single deep implementation and ships as <code>/v1/bundles-pro</code>. On EVM, use <code>bundles-pro</code> (Pro and above).</td></tr> 571 <tr><td class="param-name">/v1/fee-fingerprint/:mint</td><td>It reads the compute-unit price out of Solana <code>ComputeBudget</code> instructions â the fee setting an operator's bot carries across every wallet it drives. EVM transactions have no equivalent field, so there is nothing to re-implement.</td></tr> 572 </tbody> 573 </table> 574 </div> 575 <p class="body-text" style="margin-top:10px"><code>/v1/usage</code> reports on your key rather than on a token, so it takes no <code>chain</code> parameter. <code>/v1/trending</code>, <code>/v1/holder-overlap</code>, <code>/v1/wallet-overlap</code> and <code>/v1/wallet-reputation</code> accept <code>chain</code> as a normal query parameter alongside their own.</p> 576 577 <div class="callout callout-warn"> 578 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> 579 <div><strong>EVM endpoints are rolling out.</strong> The <code>chain</code> parameter and the plan variants above are the shipping contract, documented ahead of the switch-on so you can build against them. Until EVM activates, requests with <code>?chain=</code> set to an EVM network return <code>400</code>. Solana is unaffected. Email <a href="mailto:[email protected]" target="_blank">[email protected]</a> to be told the moment it goes live.</div> 580 </div> 581 </section> 582 583 <!-- PRICING --> 584 <section id="pricing" class="ios-web-pay"> 585 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 3h12l4 6-10 13L2 9z"/><path d="M2 9h20"/></svg></span> Pricing & Plans</h2> 586 <p class="sub">Start free. Scale as you grow. Pro and Enterprise unlock every endpoint.</p> 587 <!-- Billing period. Always visible: yearly is 20% off on every plan and 588 both rails (card and crypto) honour it. --> 589 <div id="docsBilling" style="display:flex;gap:6px;margin:0 0 10px;"> 590 <button type="button" data-period="monthly" onclick="setDocsBilling('monthly')" style="padding:7px 16px;border-radius:8px;border:1px solid var(--border-bright);background:var(--accent);color:var(--bg-primary);font-family:var(--font-body);font-size:12px;font-weight:700;cursor:pointer;">Monthly</button> 591 <button type="button" data-period="yearly" onclick="setDocsBilling('yearly')" style="padding:7px 16px;border-radius:8px;border:1px solid var(--border-bright);background:transparent;color:var(--text-primary);font-family:var(--font-body);font-size:12px;font-weight:700;cursor:pointer;">Yearly −20%</button> 592 </div> 593 <!-- One plan family since 2026-08-22: every plan covers every chain 594 (Solana, Ethereum, Base, Robinhood) â no scope toggle. --> 595 <div class="pricing-grid"> 596 <div class="price-card"> 597 <div class="price-tier">Lite</div> 598 <div class="price-amount" id="docsLiteAmt">$29 <span>/mo</span></div> 599 <ul class="price-features"> 600 <li>1,000 requests / month</li> 601 <li>15 requests / min</li> 602 <li>All 25 endpoints</li> 603 <li>All chains â Solana, Ethereum, Base & Robinhood</li> 604 <li>REST API + MCP connector (15 tools)</li> 605 <li>Email support</li> 606 </ul> 607 <button type="button" id="docsLiteBtn" class="price-btn" onclick="docsSubscribe('lite',this)">Pay with card</button> 608 <a href="/crypto-checkout?product=api_lite_all_monthly" id="docsLiteCrypto" class="price-btn price-btn-crypto">Pay with crypto</a> 609 </div> 610 <div class="price-card"> 611 <div class="price-tier">Starter</div> 612 <div class="price-amount" id="docsStarterAmt">$99 <span>/mo</span></div> 613 <ul class="price-features"> 614 <li>5,000 requests / month</li> 615 <li>30 requests / min</li> 616 <li>All 25 endpoints</li> 617 <li>All chains â Solana, Ethereum, Base & Robinhood</li> 618 <li>REST API + MCP connector (15 tools)</li> 619 <li>Email support</li> 620 </ul> 621 <button type="button" id="docsStarterBtn" class="price-btn" onclick="docsSubscribe('starter',this)">Pay with card</button> 622 <a href="/crypto-checkout?product=api_starter_all_monthly" id="docsStarterCrypto" class="price-btn price-btn-crypto">Pay with crypto</a> 623 </div> 624 <div class="price-card"> 625 <div class="price-tier">Growth</div> 626 <div class="price-amount" id="docsGrowthAmt">$199 <span>/mo</span></div> 627 <ul class="price-features"> 628 <li>10,000 requests / month</li> 629 <li>45 requests / min</li> 630 <li>All 25 endpoints</li> 631 <li>All chains — Solana, Ethereum, Base & Robinhood</li> 632 <li>REST API + MCP connector (15 tools)</li> 633 <li>Email support</li> 634 </ul> 635 <button type="button" id="docsGrowthBtn" class="price-btn" onclick="docsSubscribe('growth',this)">Pay with card</button> 636 <a href="/crypto-checkout?product=api_growth_all_monthly" id="docsGrowthCrypto" class="price-btn price-btn-crypto">Pay with crypto</a> 637 </div> 638 <div class="price-card featured"> 639 <div class="price-tier">Pro</div> 640 <div class="price-amount" id="docsProAmt">$399 <span>/mo</span></div> 641 <ul class="price-features"> 642 <li>20,000 requests / month</li> 643 <li>60 requests / min</li> 644 <li>All 25 endpoints</li> 645 <li>All chains â Solana, Ethereum, Base & Robinhood</li> 646 <li>REST API + MCP connector (15 tools)</li> 647 <li>
647Priority support</li> 648 </ul> 649 <button type="button" id="docsProBtn" class="price-btn" onclick="docsSubscribe('pro',this)">Pay with card</button> 650 <a href="/crypto-checkout?product=api_pro_all_monthly" id="docsProCrypto" class="price-btn price-btn-crypto">Pay with crypto</a> 651 </div> 652 <div class="price-card"> 653 <div class="price-tier">Enterprise</div> 654 <div class="price-amount" id="docsEntAmt">$1,999 <span>/mo</span></div> 655 <ul class="price-features"> 656 <li>100,000 requests / month</li> 657 <li>200 requests / min</li> 658 <li>All 25 endpoints</li> 659 <li>All chains â Solana, Ethereum, Base & Robinhood</li> 660 <li>REST API + MCP connector (15 tools)</li> 661 <li>Dedicated support & SLA</li> 662 </ul> 663 <button type="button" id="docsEntBtn" class="price-btn price-btn-secondary" onclick="docsSubscribe('enterprise',this)">Pay with card</button> 664 <a href="/crypto-checkout?product=api_enterprise_all_monthly" id="docsEntCrypto" class="price-btn price-btn-crypto">Pay with crypto</a> 665 </div> 666 </div> 667 668 <h3>What each plan includes</h3> 669 <p class="body-text">Every paid plan includes <strong>all 25 endpoints on every chain</strong> â plans differ by monthly request volume, rate limits and support. Expensive deep-analysis calls are metered in request units, so heavy endpoints draw more units per call. The free tier covers 6 endpoints. Calling past your plan returns <code>403</code> or <code>402</code> with upgrade instructions.</p> 670 671 <div style="overflow-x:auto"> 672 <table class="param-table" style="margin-top:14px"> 673 <thead><tr><th>Plan</th><th>Endpoints</th><th>What it adds</th></tr></thead> 674 <tbody> 675 <tr> 676 <td class="param-name">Free</td> 677 <td>6</td> 678 <td><code>analyze</code>, <code>rug-score</code>, <code>token-price</code>, <code>trending</code>, <code>holders</code>, <code>kol</code></td> 679 </tr> 680 <tr> 681 <td class="param-name">Starter</td> 682 <td>All 23</td> 683 <td>5,000 units/mo · 30 req/min â every endpoint incl. the deep-analysis modules (<code>funding-origin</code>, <code>funding-graph</code>, <code>sybil-cluster</code>, <code>fee-fingerprint</code>, <code>bundles-pro</code>, <code>historical-bundles</code>, <code>holder-overlap</code>, <code>wallet-overlap</code>, <code>wallet-reputation</code>)</td> 684 </tr> 685 <tr> 686 <td class="param-name">Pro</td> 687 <td>All 23</td> 688 <td>20,000 units/mo · 60 req/min · priority support</td> 689 </tr> 690 <tr> 691 <td class="param-name">Enterprise</td> 692 <td>All 23</td> 693 <td>100,000 units/mo · 200 req/min · dedicated support & SLA</td> 694 </tr> 695 </tbody> 696 </table> 697 </div> 698 699 <p class="body-text" style="margin-top:14px">Every plan comes in two variants. The <strong>Solana</strong> variant answers for Solana tokens only. The <strong>All-Chains</strong> variant answers the same endpoints on Ethereum, Base and Robinhood Chain as well â the endpoint list is identical, only the chains differ. See <a href="#chains">Chains</a>.</p> 700 </section> 701 702 <!-- OVERAGE CREDITS --> 703 <section id="overage-credits"> 704 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v12M6 12h12"/></svg></span> Overage Credits</h2> 705 <p class="sub">Keep making requests after your daily limit â pay-per-use, no plan upgrade required.</p> 706 707 <p class="body-text">When your daily request limit is reached, the API normally returns <code>429 Too Many Requests</code>. With overage credits enabled, requests beyond your daily limit are automatically fulfilled using credits instead of being blocked. Each overage request costs <strong>1 credit ($0.02)</strong>.</p> 708 709 <h3>How It Works</h3> 710 <p class="body-text">1. <strong>Purchase a credit pack</strong> via the <a href="https://defade.org/dashboard">dashboard</a> (card or USDC) or the API. 2. <strong>Enable overage</strong> on your API key (opt-in via dashboard toggle). 3. When you hit your daily limit, requests automatically consume credits. 4. When credits run out, the standard <code>429</code> response resumes.</p> 711 712 <div class="ios-web-pay"> 713 <h3>Credit Packs</h3> 714 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm)"> 715 <table class="field-table"> 716 <thead><tr><th>
716Pack</th><th>Price</th><th>Credits</th><th>Cost / Request</th><th>Bonus</th></tr></thead> 717 <tbody> 718 <tr><td class="fname">Small</td><td>$5</td><td>250</td><td>$0.020</td><td>â</td></tr> 719 <tr><td class="fname">Medium</td><td>$20</td><td>1,050</td><td>~$0.019</td><td style="color:var(--accent);font-weight:600">+5%</td></tr> 720 <tr><td class="fname">Large</td><td>$50</td><td>2,750</td><td>~$0.018</td><td style="color:var(--accent);font-weight:600">+10%</td></tr> 721 </tbody> 722 </table> 723 </div> 724 </div> 725 726 <h3>Buy Credits via API</h3> 727 <div class="endpoint" style="margin-bottom:16px"> 728 <div class="endpoint-header" style="cursor:default"> 729 <span class="method-badge method-post">POST</span> 730 <span class="endpoint-path">/api/stripe/buy-credits</span> 731 <span class="tag tag-paid">No Auth Required</span> 732 </div> 733 </div> 734 <p class="body-text">Returns a Stripe checkout URL for one-time credit purchase. After payment, credits are added to your key automatically.</p> 735 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm)"> 736 <table class="param-table"> 737 <thead><tr><th>Field</th><th>Type</th><th>Required</th><th>Description</th></tr></thead> 738 <tbody> 739 <tr><td class="param-name">pack</td><td class="param-type">string</td><td><span class="required">Required</span></td><td>Credit pack size: <code>"small"</code>, <code>"medium"</code>, or <code>"large"</code></td></tr> 740 <tr><td class="param-name">apiKey</td><td class="param-type">string</td><td><span class="required">Required</span></td><td>The API key to add credits to (your <code>df_...</code> key)</td></tr> 741 </tbody> 742 </table> 743 </div> 744 745 <h3>Response Headers</h3> 746 <p class="body-text">When a request uses an overage credit, two extra headers are included in the response:</p> 747 <div class="rl-grid"> 748 <div class="rl-item"> 749 <div class="rl-header-name">X-Credit-Used</div> 750 <div class="rl-desc">Set to <code>1</code> when a credit was consumed for this request.</div> 751 </div> 752 <div class="rl-item"> 753 <div class="rl-header-name">X-Credit-Balance</div> 754 <div class="rl-desc">Your remaining credit balance after this request.</div> 755 </div> 756 </div> 757 758 <h3>429 Response with Credits Info</h3> 759 <p class="body-text">When your daily limit is hit and credits are unavailable or disabled, the <code>429</code> response includes a <code>credits</code> object:</p> 760 <div class="code-block-solo"> 761<pre>{ 762 <span class="key-c">"error"</span>: <span class="str">"Daily limit exceeded"</span>, 763 <span class="key-c">"limit"</span>: <span class="str">"1000/day"</span>, 764 <span class="key-c">"resetsAt"</span>: <span class="str">"midnight UTC"</span>, 765 <span class="key-c">"credits"</span>: { 766 <span class="key-c">"enabled"</span>: <span class="fn">false</span>, 767 <span class="key-c">"balance"</span>: <span class="fn">0</span>, 768 <span class="key-c">"costPerRequest"</span>: <span class="str">"$0.02"</span>, 769 <span class="key-c">"hint"</span>: <span class="str">"Enable overage credits in your dashboard..."</span> 770 } 771}</pre> 772 </div> 773 774 <div class="callout callout-info"> 775 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--blue)" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> 776 <div><strong>Credits never expire.</strong> Once purchased, credits remain on your key until used. Your credit balance and overage status are visible in the <a href="https://defade.org/dashboard">dashboard</a> and via the <code>/v1/usage</code> endpoint.</div> 777 </div> 778 </section> 779 780 <!-- RATE LIMITS --> 781 <section id="rate-limits"> 782 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg></span> Rate Limits</h2> 783 <p class="sub">Rate limits are enforced per API key at both per-minute and daily granularity.</p> 784 <p class="body-text">
784When you exceed your per-minute rate limit, the API returns <code>429 Too Many Requests</code> with a <code>retryAfter</code> field (in seconds). When you exceed your daily limit, the request is blocked unless you have <a href="#overage-credits">overage credits</a> enabled â in which case each extra request consumes 1 credit ($0.02). Rate limit status is included in every response via headers:</p> 785 786 <div class="rl-grid"> 787 <div class="rl-item"> 788 <div class="rl-header-name">X-RateLimit-Limit</div> 789 <div class="rl-desc">Maximum requests allowed per minute for your tier.</div> 790 </div> 791 <div class="rl-item"> 792 <div class="rl-header-name">X-RateLimit-Remaining</div> 793 <div class="rl-desc">Requests remaining in the current 60-second window.</div> 794 </div> 795 </div> 796 797 <h3>Limits by Plan</h3> 798 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm)"> 799 <table class="field-table"> 800 <thead><tr><th>Plan</th><th>Per Minute</th><th>Per Day</th><th>Daily Reset</th></tr></thead> 801 <tbody> 802 <tr><td class="fname">Free</td><td>10</td><td>100</td><td>Midnight UTC</td></tr> 803 <tr><td class="fname">Starter</td><td>30</td><td>1,000</td><td>Midnight UTC</td></tr> 804 <tr><td class="fname">Pro</td><td>60</td><td>5,000</td><td>Midnight UTC</td></tr> 805 <tr><td class="fname">Enterprise</td><td>200</td><td>50,000</td><td>Midnight UTC</td></tr> 806 </tbody> 807 </table> 808 </div> 809 810 <div class="callout callout-tip"> 811 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2"><path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg> 812 <div><strong>Best practice:</strong> Cache results on your end. Token risk profiles don't change every second â caching for 60â300 seconds dramatically reduces your API usage without sacrificing freshness.</div> 813 </div> 814 </section> 815 816 <!-- ERRORS --> 817 <section id="errors"> 818 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></span> Error Handling</h2> 819 <p class="sub">All errors return a consistent JSON structure with an <code style="color:var(--blue)">error</code> field and optionally a <code style="color:var(--blue)">message</code> with more detail.</p> 820 821 <h3>Error Response Format</h3> 822 <div class="code-block-solo"> 823<pre>{ 824 <span class="key-c">"error"</span>: <span class="str">"Rate limit exceeded"</span>, 825 <span class="key-c">"limit"</span>: <span class="str">"10/min"</span>, 826 <span class="key-c">"retryAfter"</span>: <span class="fn">23</span> 827}</pre> 828 </div> 829 830 <h3>HTTP Status Codes</h3> 831 <div style="overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius)"> 832 <table class="error-table"> 833 <thead><tr><th>Status</th><th>Meaning</th><th>Common Cause</th></tr></thead> 834 <tbody> 835 <tr><td class="status-code" style="color:var(--accent)">200</td><td>Success</td><td>Request completed. Response body contains the data.</td></tr> 836 <tr><td class="status-code s4">400</td><td>Bad Request</td><td>Invalid mint address format or malformed request body.</td></tr> 837 <tr><td class="status-code s4">401</td><td>Unauthorized</td><td>Missing or invalid API key. Check the <code>x-api-key</code> header.</td></tr> 838 <tr><td class="status-code s4">403</td><td>Forbidden</td><td>Endpoint not available on your plan. Upgrade to access.</td></tr> 839 <tr><td class="status-code s4">404</td><td>Not Found</td><td>Token mint address not found on Solana or not yet indexed.</td></tr> 840 <tr><td class="status-code s4">429</td><td>Too Many Requests</td><td>Rate limit exceeded. Check <code>retryAfter</code> and back off.</td></tr> 841 <tr><td class="status-code s5">500</td><td>Internal Error</td><td>Server error. Retry after a moment. If persistent, contact support.</td></tr> 842 <tr><td class="status-code s5">503</td><td>Service Unavailable</td><td>Upstream RPC provider temporarily down. Automatic recovery.</td></tr> 843 </tbody> 844 </table> 845 </div> 846 </section> 847 848 <!-- SDKs --> 849 <section id="sdks"> 850 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg></span> SDKs & Integration</h2> 851 <p class="sub">The DeFade API is a standard REST API â it works with any HTTP client in any language.</p> 852 853 <h3>Official JavaScript SDK</h3> 854 <p class="body-text">Zero-dependency client for Node 18+, CJS and ESM, with TypeScript types â open source at <a href="https://github.com/DeFadeLtd/defade-sdk" target="_blank" rel="noopener">github.com/DeFadeLtd/defade-sdk</a>.</p> 855 <div class="code-block-solo" id="sdk-npm"> 856 <button class="copy-btn" onclick="copyBlock(this,'sdk-npm')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 857<pre><span class="dim">npm</span> install defade <span class="comment"># or: npm install github:DeFadeLtd/defade-sdk</span></pre> 858 </div> 859 <div class="code-block-solo" id="sdk-official"> 860 <button class="copy-btn" onclick="copyBlock(this,'sdk-official')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 861<pre><span class="kw">
861import</span> DeFade <span class="kw">from</span> <span class="str">'defade'</span>; 862 863<span class="kw">const</span> client = <span class="kw">new</span> <span class="fn">DeFade</span>({ <span class="key-c">apiKey</span>: process.env.<span class="fn">DEFADE_API_KEY</span> }); 864 865<span class="kw">const</span> scan = <span class="kw">await</span> client.<span class="fn">analyze</span>(<span class="str">'TOKEN_MINT'</span>); <span class="comment">// safety score: 100 = clean</span> 866<span class="kw">const</span> risk = <span class="kw">await</span> client.<span class="fn">rugScore</span>(<span class="str">'TOKEN_MINT'</span>); <span class="comment">// rug probability: 100 = dangerous</span> 867<span class="kw">const</span> eth = <span class="kw">await</span> client.<span class="fn">holders</span>(<span class="str">'0xâ¦'</span>, { <span class="key-c">chain</span>: <span class="str">'ethereum'</span> });</pre> 868 </div> 869 870 <h3>Plain JavaScript / Node.js</h3> 871 <div class="code-block-solo" id="sdk-js"> 872 <button class="copy-btn" onclick="copyBlock(this,'sdk-js')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 873<pre><span class="comment">// Simple wrapper function</span> 874<span class="kw">const</span> DEFADE_KEY = process.env.<span class="fn">DEFADE_API_KEY</span>; 875 876<span class="kw">async function</span> <span class="fn">defade</span>(endpoint, mint = <span class="str">''</span>) { 877 <span class="kw">const</span> url = <span class="str">`https://api.defade.org/v1/${</span>endpoint<span class="str">}${</span>
877mint ? <span class="str">`/${</span>mint<span class="str">}`</span> : <span class="str">''</span><span class="str">}`</span>; 878 <span class="kw">const</span> res = <span class="kw">await</span> <span class="fn">fetch</span>(url, { 879 <span class="key-c">headers</span>: { <span class="str">'x-api-key'</span>: DEFADE_KEY } 880 }); 881 <span class="kw">if</span> (!res.ok) <span class="kw">throw new</span> Error(<span class="str">`DeFade API ${</span>res.status<span class="str">}: ${</span>(<span class="kw">await</span> res.<span class="fn">json</span>()).error<span class="str">}`</span>); 882 <span class="kw">return</span> res.<span class="fn">json</span>(); 883} 884 885<span class="comment">// Usage</span> 886<span class="kw">const</span> analysis = <span class="kw">await</span> <span class="fn">defade</span>(<span class="str">'analyze'</span>, <span class="str">'TOKEN_MINT'</span>); 887<span class="kw">const</span> trending = <span class="kw">await</span> <span class="fn">defade</span>(<span class="str">'trending'</span>);</pre> 888 </div> 889 890 <h3>Python</h3> 891 <div class="code-block-solo" id="sdk-py"> 892 <button class="copy-btn" onclick="copyBlock(this,'sdk-py')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> 893<pre><span class="kw">import</span> os, requests 894 895DEFADE_KEY = os.environ[<span class="str">'DEFADE_API_KEY'</span>] 896BASE = <span class="str">'https://api.defade.org/v1'</span> 897 898<span class="kw">def</span> <span class="fn">defade</span>(endpoint, mint=<span class="str">''</span>): 899 url = <span class="str">f'{BASE}/{endpoint}'</span> + (<span class="str">f'/{mint}'</span> <span class="kw">if</span> mint <span class="kw">else</span> <span class="str">''</span>) 900 r = requests.<span class="fn">get</span>(url, headers={<span class="str">'x-api-key'</span>: DEFADE_KEY}) 901 r.<span class="fn">raise_for_status</span>() 902 <span class="kw">return</span> r.<span class="fn">json</span>() 903 904<span class="comment"># Usage</span> 905analysis = <span class="fn">defade</span>(<span class="str">'analyze'</span>, <span class="str">'TOKEN_MINT'</span>) 906trending = <span class="fn">defade</span>(<span class="str">'trending'</span>)</pre> 907 </div> 908 909 <h3>Other Integrations</h3> 910 <p class="body-text">DeFade also offers a <a href="https://t.me/DeFadeAnalyzerBot" target="_blank">Telegram bot</a> (@DeFadeAnalyzerBot) for instant token checks, a <a href="https://defade.org" target="_blank">Chrome extension</a> that auto-detects tokens on DEX pages, and a community channel at <a href="https://t.me/DeFadeChat" target="_blank">t.me/DeFadeChat</a>.</p> 911 </section> 912 913 <!-- MCP CONNECTOR --> 914 <section id="mcp"> 915 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a3 3 0 00-3 3v1a3 3 0 006 0V5a3 3 0 00-3-3z"/><path d="M12 9v4"/><path d="M5 22v-5a7 7 0 0114 0v5"/></svg></span> MCP Connector</h2> 916 <p class="sub">The same API, spoken as <a href="https://modelcontextprotocol.io" target="_blank" rel="noopener">Model Context Protocol</a>, so Claude, ChatGPT and any other MCP client can run DeFade scans directly in a conversation. One endpoint, no SDK, no separate key.</p> 917 918 <h3>Connect</h3> 919 <p class="body-text">Add a custom connector pointing at the URL below, with your API key in the query string. Connector UIs only take a URL, which is why the key goes there; <code>x-api-key</code> and <code>Authorization: Bearer</code> also work for clients that let you set headers.</p> 920 <div class="code-block-solo"> 921<pre>https://api.defade.org/mcp?api_key=<span class="str">YOUR_KEY</span></pre> 922 </div> 923 <p class="body-text"><strong>Claude</strong> â Settings â Connectors â Add custom connector â paste the URL. <strong>ChatGPT</strong> â Settings â Connectors â Add â paste the URL. Both then list DeFade's tools and call them when a question needs one.</p> 924 <h3 id="mcp-keys">Getting a key</h3> 925 <p class="body-text">Two keys open the connector, and they are different products:</p> 926 <p class="body-text"><strong>An API-plan key</strong> (<code>df_â¦</code>). Buy Starter, Pro or Enterprise under <a href="#pricing">Pricing</a> or on <a href="https://defade.org/developers">defade.org/developers</a> (card or crypto, key delivered immediately), or <a href="https://defade.org/developers#keygen">request a free 7-day trial</a>. It works on the REST API and in the connector alike, metered in units against the plan. A trial key reaches only <code>get_token_scan</code>, <code>get_rug_score</code>, <code>get_holders</code>, <code>get_token_price</code> and <code>get_usage</code>, on any chain.</p> 927 <p class="body-text"><strong>The Pro connector key</strong> (<code>df_mcp_â¦</code>), included with a <a href="https://defade.org/pricing">DeFade Pro</a> web subscription. Issue it from the <a href="https://defade.org/dashboard">dashboard</a> under "Claude & ChatGPT connector" and paste the URL it gives you. It reaches all fifteen tools on every chain, and every tool call spends a scan from the plan's monthly allowance â the same one the website uses, one scan per distinct token per UTC day however many tools you run on it â so <code>get_usage</code> reports scans, not units. It only works through the connector: a direct REST call answers <code>403 mcp_only</code>, and it stops working when the subscription lapses. It is not an API key, and it does not turn a Pro subscription into an API plan.</p> 928 929 <h3>Tools</h3> 930 <p class="body-text">Fifteen tools, one per module, each mapping to the <code>/v1</code> endpoint of the same name:</p> 931 <div class="code-block-solo"> 932<pre>get_token_scan get_rug_score get_holders 933get_whales get_liquidity get_launch_bundles 934get_launch_snipers get_wallet_links get_smart_money 935get_dev_tracker get_funding_sources get_lookalike_cluster
935s 936get_fee_fingerprint get_token_price get_usage</pre> 937 </div> 938 <p class="body-text">Every tool takes an <code>address</code> and an optional <code>chain</code>, exactly like the REST route behind it; <code>get_token_price</code> also takes an optional <code>timeframe</code> (the route's <code>?type=</code>), so <code>1D</code> reaches back up to a year of daily candles. Nothing here writes, trades or spends â all fifteen are read-only.</p> 939 940 <h3>Billing and limits</h3> 941 <p class="body-text">A tool call <em>is</em> an API call: it runs through the same key, the same plan endpoint list, the same chain scope, the same unit quota and the same rate limits as a REST request, and shows up in your usage the same way. Connector traffic is tagged <code>mcp</code> on the usage dashboard so you can tell it apart from your own integrations. There is no separate MCP plan or price. With the Pro connector key the meter is the web plan's scan allowance instead (see <a href="#mcp-keys">Getting a key</a>).</p> 942 943 <h3>Two scores, opposite directions</h3> 944 <p class="body-text">Worth knowing before you read an assistant's answer: <code>get_token_scan</code> returns <code>risk.score</code>, a <strong>safety</strong> score where 100 is clean, while <code>get_rug_score</code> returns <code>rugScore</code>, a rug pull <strong>probability</strong> where high is dangerous. The connector states this in its handshake instructions and repeats it on every result, so a model should not confuse them â but if you are reading raw output, check which tool produced it.</p> 945 946 <h3>Calling it directly</h3> 947 <p class="body-text">It is plain JSON-RPC 2.0 over HTTP POST (stateless Streamable HTTP â no session header, no SSE stream), so you can drive it with curl:</p> 948 <div class="code-block-solo"> 949<pre>curl -X POST <span class="str">"https://api.defade.org/mcp?api_key=YOUR_KEY"</span> \ 950 -H <span class="str">"Content-Type: application/json"</span> \ 951 -d <span class="str">'{"jsonrpc":"2.0","id":1,"method":"tools/list"}'</span> 952 953curl -X POST <span class="str">"https://api.defade.org/mcp?api_key=YOUR_KEY"</span> \ 954 -H <span class="str">"Content-Type: application/json"</span> \ 955 -d <span class="str">'{"jsonrpc":"2.0","id":2,"method":"tools/call", 956 "params":{"name":"get_token_scan", 957 "arguments":{"address":"YOUR_MINT","chain":"solana"}}}'</span></pre> 958 </div> 959 <p class="body-text">A failed call comes back as a tool result with <code>isError</code> set and the API's own message inside it â wrong plan, bad address, allowance spent â rather than a bare protocol error, so the assistant can tell you what actually went wrong.</p> 960 </section> 961 962 <!-- CHANGELOG --> 963 <section id="changelog"> 964 <h2><span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg></span> Changelog</h2> 965 <p class="sub">Changes to the shape of a response, and anything else that can break an integration written against an earlier version. Endpoints added, and fields added to an existing response, are safe to ignore â they are listed so you know what is new.</p> 966 967 <h3>2026-10-01 · Changed · <code>/v1/rug-score</code> answers within a time budget</h3> 968 <p class="body-text">The call used to run the full analysis first, then its Pro modules, and wait for the slowest of them — a median of 11–13 s and a 95th percentile at the 25 s ceiling. It now starts the launch modules alongside the analysis and answers after a budget, <strong>5 s by default</strong>: the free checks and every module that has landed are scored, and the rest is named in a new <code>pending</code> array while it keeps computing server-side. <code>complete</code> is <code>true</code> when nothing is pending, and <code>coverage</code> reads <code>partial</code> until then. Pass <code>?wait=full</code> to wait for every module as before (up to 25 s), or <code>?wait=<seconds></code>
968 to choose your own budget. <strong>If your integration needs the complete score in one call, add <code>?wait=full</code>.</strong> The MCP tool always waits for the complete answer.</p> 969 970 <h3>2026-09-30 · Added · <code>/v1/wallet-reputation/:wallet</code> and <code>/v1/wallet-overlap</code></h3> 971 <p class="body-text"><code>/v1/wallet-reputation/:wallet</code> is the Wallet Lookup page on the API: one wallet's record across every token DeFade scanned — tokens flagged in, confirmed rugs, the role on each, a tier verdict — with a <code>labelGlossary</code> that says what each role means. It is about a wallet rather than a token, so its envelope carries <code>wallet</code> and <code>chain</code> in place of <code>token</code>. <code>/v1/wallet-overlap?mints=A,B(,C)</code> returns the wallets holding two or more of the given tokens. Nothing about existing endpoints changed.</p> 972 973 <h3>2026-09-07 · <span style="color:var(--red)">Breaking</span> · <code>/v1/trending?chain=</code> returns a named array on EVM chains too</h3> 974 <p class="body-text">The 2026-08-28 fix below landed on the Solana path only. On <code>ethereum</code>, <code>base</code> and <code>robinhood</code> the feed was still spread into the envelope, so the same endpoint answered two different shapes depending on <code>?chain=</code> — a named <code>trending</code> array on Solana, numeric keys everywhere else. The EVM response now carries the same <code>trending</code> array. <strong>If your integration reads numeric keys off an EVM trending call, change it to <code>res.trending</code>;</strong> the Solana path is unaffected, and an error still puts <code>error</code> at the top level rather than inside <code>trending</code>.</p> 975 976 <h3>2026-09-07 · Added · trial keys reach every chain</h3> 977 <p class="body-text">The free 7-day trial key was Solana-only. It now covers every chain the API covers — Solana, Ethereum, Base and Robinhood — on the same six endpoints, at the same <code>10 req/min</code>, <code>100 req/day</code> and <code>3,000 units/month</code>. An EVM call from a trial key costs one unit, the same as a Solana one. Paid plans were already all-chains and are unchanged.</p> 978 979 <h3>2026-08-28 · Added · MCP connector at <code>/mcp</code></h3> 980 <p class="body-text">The <code>/v1</code> surface is now also reachable over the Model Context Protocol, so Claude, ChatGPT and other MCP clients can run scans in-conversation. Fifteen read-only tools, metered against your existing key exactly like REST calls. Nothing about the REST API changed. See <a href="#mcp">MCP Connector</a>.</p> 981 982 <h3>2026-08-28 · <span style="color:var(--red)">Breaking</span> · <code>/v1/trending</code> returns a named array</h3> 983 <p class="body-text">The feed is answered as a JSON array, and the endpoint used to spread it into the response envelope. That scattered the tokens across numeric keys â <code>"0"</code>, <code>"1"</code>, <code>"2"</code> ⦠â next to <code>timestamp</code> and <code>poweredBy</code>, so reading the list meant subtracting the envelope and collecting whatever was left. The tokens now arrive in a <code>trending</code> array.</p> 984 <div class="code-block-solo"> 985<pre><span class="comment">// before</span> 986{ <span class="key-c">"timestamp"</span>: <span class="str">"â¦"</span>, <span class="key-c">"0"</span>: { <span class="key-c">"symbol"</span>: <span class="str">"EX"</span> }, <span class="key-c">"1"</span>: { <span class="key-c">"symbol"</span>: <span class="str">"FOO"</span> }, <span class="key-c">"poweredBy"</span>: <span class="str">"DeFade.org"</span> } 987 988<span class="comment">// after</span> 989{ <span class="key-c">"timestamp"</span>: <span class="str">"â¦"</span>, <span class="key-c">"trending"</span>: [ { <span class="key-c">"symbol"</span>: <span class="str">"EX"</span> }, { <span class="key-c">"symbol"</span>: <span class="str">"FOO"</span> } ], <span class="key-c">"poweredBy"</span>: <span class="str">"DeFade.org"</span> }</pre> 990 </div> 991 <p class="body-text"><strong>
991If you read numeric keys, you must change your code.</strong> Anywhere you filtered the envelope out and took the rest â <code>Object.entries(res).filter(([k]) => !isNaN(k))</code> or similar â becomes <code>res.trending</code>. An error response is unaffected: a failure still puts <code>error</code> at the top level rather than inside <code>trending</code>.</p> 992 993 <h3>2026-08-28 · Added · <code>/v1/dev-tracker</code> says where the dev wallet came from</h3> 994 <p class="body-text">Two new fields. <code>creatorSource</code> names the signal that identified the wallet, and <code>creatorInferred</code> is true when that signal does not identify a person â a launchpad stamps one authority across every token it mints, so an authority-derived address is a guess, not a dev. Treat an inferred wallet's position as unconfirmed. Existing fields are unchanged.</p> 995 996 <h3>2026-08-28 · Fixed · <code>/v1/dev-tracker</code> <code>lastActivity</code> is populated</h3> 997 <p class="body-text">It had always been null. It is now the unix timestamp of the dev's most recent move of the token, across every bucket the endpoint tracks, and null only when the wallet has never moved it.</p> 998 999 <h3>2026-08-28 · Docs · response schemas rewritten against the endpoints</h3> 1000 <p class="body-text">No API behaviour changed here, but the reference on this page did. Every response sample used to open with a <code>"mint"</code> key that no endpoint returns â responses carry <code>token</code>, <code>timestamp</code> and <code>poweredBy</code> â and several field lists named fields that do not exist (<code>/v1/analyze</code> listed <code>rugScore</code> and <code>riskLevel</code>; <code>/v1/holders</code> listed <code>top10Pct</code>; <code>/v1/whales</code>, <code>/v1/bundles</code> and <code>/v1/snipers</code> listed counts that live inside <code>summary</code>). Every entry has been rewritten against the response its endpoint actually sends. If you built against the old schemas and something never worked, this is why.</p> 1001 1002 <h3>Older changes</h3> 1003 <p class="body-text">This log starts on 2026-08-28. Earlier changes were not recorded. For anything before that, the endpoint reference above describes current behaviour.</p> 1004 </section> 1005 1006</div> 1007 1008<!-- FOOTER --> 1009<footer class="footer"> 1010 <div>© 2026 DeFade Ltd · <a href="https://defade.org" target="_blank">defade.org</a></div> 1011 <div>Contact: <a href="mailto:[email protected]" target="_blank">[email protected]</a> · <a href="https://x.com/DeFade_" target="_blank">@DeFade_</a> · <a href="https://t.me/DeFadeChat" target="_blank">Telegram</a></div> 1012</footer> 1013
1014<script> 1015// ======== ENDPOINT DATA ======== 1016const endpoints = [ 1017 { 1018 method:'GET', path:'/v1/analyze/:mint', desc:'Full risk analysis', id:'analyze', 1019 tier:'free', 1020 detail:'Runs the full core analysis suite in a single call and returns a comprehensive risk report. This is the primary endpoint for most use cases â it combines rug score, liquidity, holders, bundles, insider network, and more into one response.', 1021 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1022 fields:[ 1023 {n:'success',t:'boolean',d:'Whether the scan completed.'}, 1024 {n:'token',t:'object',d:'Full token metadata \u2014 <code>name</code>, <code>symbol</code>, <code>mint</code>, <code>supply</code>, <code>decimals</code>, <code>creator</code>, <code>creatorSource</code>, <code>mintAuthority</code>, <code>freezeAuthority</code>, <code>dexPaid</code>, <code>marketCap</code>, <code>liquidity</code>, <code>priceUsd</code>, <code>priceChange</code>, <code>volume</code>, <code>volumeBot</code> and a <code>timeline</code>. Note this REPLACES the envelope\u0027s token string.'}, 1025 {n:'holders',t:'object',d:'Same body as /v1/holders: <code>totalHolders</code>, <code>topHolders</code>, <code>concentration</code>, <code>protocolHoldings</code>, <code>lockedSupply</code>, <code>deferredUnlock</code>, <code>bundles</code>.'}, 1026 {n:'creator',t:'object',d:'<code>address</code>, <code>walletAgeDays</code>, <code>solBalance</code>, <code>totalTransactions</code>, <code>tokenCreations</code>, <code>recentTokens</code>, <code>riskLevel</code>.'}, 1027 {n:'risk',t:'object',d:'The legacy safety score: <code>score</code>, <code>rating</code>, <code>color</code>, <code>flags</code>. <strong>Its scale is INVERTED relative to rugScore</strong> \u2014 100 is safe here, 0 is critical. Ratings run PROBABLY SAFE / PROCEED WITH CAUTION / ELEVATED RISK / HIGH RISK / VERY HIGH RISK / LIKELY RUG. For the rug probability model call /v1/rug-score.'}, 1028 {n:'scanCount',t:'number',d:'How many times this token was scanned in the last 24 hours, on every DeFade surface (web, app, extension, Telegram, API) by every user, including this scan.'}, 1029 {n:'scanWindow',t:'string',d:'The window <code>scanCount</code> covers: <code>24h</code>.'}, 1030 {n:'analyzedAt',t:'string',d:'ISO timestamp of the scan itself, distinct from the envelope timestamp.'}, 1031 ], 1032 response:`{ 1033 "timestamp": "2026-08-28T09:30:11.402Z", 1034 "success": true, 1035 "token": { "name": "Example", "symbol": "EX", "mint": "7xK...", "creator": "9qR...", "creatorSource": "mint_tx" }, 1036 "holders": { "totalHolders": 412, "concentration": { "top5": 18.2, "top10": 26.9, "top20": 34.1 } }, 1037 "creator": { "address": "9qR...", "walletAgeDays": 96, "tokenCreations": 3 }, 1038 "risk": { "score": 42, "rating": "SOME RISK", "color": "orange", "flags": [] }, 1039 "scanCount": 17, 1040 "scanWindow": "24h",
1041 "analyzedAt": "2026-08-28T09:30:11.284Z", 1042 "poweredBy": "DeFade.org" 1043}` 1044 }, 1045 { 1046 method:'GET', path:'/v1/rug-score/:mint', desc:'Rug probability score', id:'rug-score', 1047 tier:'free', 1048 detail:'Returns just the rug score and risk level â a lightweight call when you only need the risk classification without the full analysis breakdown. <strong>Answers within a time budget</strong> (default 5 s): the free checks plus every Pro module that has landed by then are scored, and anything still computing is named in <code>pending</code> and keeps running server-side, so a second call â or one with <code>?wait=full</code> â returns the complete score.', 1049 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'},{name:'wait',type:'string',required:false,desc:'How long to wait for the Pro modules before answering: a number of seconds (0â25), or <code>full</code> to wait for every module (up to 25 s, the previous behaviour). Default 5.'}], 1050 fields:[ 1051 {n:'rugScore',t:'number',d:'Rug probability, 0 (safe) to 100 (critical).'}, 1052 {n:'verdict',t:'string',d:'The label for that score, in full: <code>PROBABLY SAFE</code> (<25), <code>SOME RISK</code> (25+), <code>ELEVATED RISK</code> (45+), <code>HIGH RISK</code> (60+), <code>EXTREME RISK</code> (75+) \u2014 or a state that overrides the bands: <code>RUGGED / DEAD</code>, <code>ABANDONED / DEAD</code>, <code>NEVER BONDED</code>. <code>verdictColor</code> is the matching colour.'}, 1053 {n:'scoreLabel',t:'string|null',d:'<code>"NEVER BONDED"</code> when DeFade\'s own pages print that state instead of the percentage (a coin still on its launchpad curve has no pool to pull). <code>rugScore</code> is still returned as a number. <code>null</code> otherwise.'}, 1054 {n:'signals',t:'array',d:'Every contributing signal: what fired, its weight and its explanation. Signals marked pro-only are omitted on non-Pro keys.'}, 1055 {n:'coverage',t:'string',d:'<code>full</code> when the Pro signal set contributed, <code>partial</code> while something is still in <code>pending</code>, <code>free</code> when only the free checks did \u2014 a partial or free score has seen less evidence.'}, 1056 {n:'pending',t:'array',d:'Modules that were still computing when the call answered (<code>liquidity</code>, <code>snipers</code>, <code>insider-network</code>, <code>dev-tracker</code>). Empty when the score is complete. They keep running: call again, or pass <code>?wait=full</code>.'}, 1057 {n:'complete',t:'boolean',d:'<code>true</code> when <code>pending</code> is empty.'}, 1058 {n:'bundleSubScore',t:'number',d:'The bundle component of the score; <code>bundleEngine</code> names which bundle detector produced it.'}, 1059 {n:'fusion',t:'object',d:'Cross-signal wallet correlation. On non-Pro keys <code>fusion.wallets</code> is empty and <code>fusion.walletsLocked</code> is true.'}, 1060 {n:'proChecksLocked',t:'number',d:'How many Pro-only checks were withheld from this response.'}, 1061 ], 1062 response:`{ 1063 "token": "7xK...", 1064 "timestamp": "2026-08-28T09:30:11.402Z", 1065 "rugScore": 72, 1066 "verdict": "HIGH RISK", 1067 "verdictColor": "red", 1068 "signals": [ { "id": "dev_transferred", "weight": 18, "label": "Dev moved 20% of supply to a fresh wallet" } ], 1069 "bundleSubScore": 14, 1070 "bundleEngine": "v2", 1071 "coverage": "partial", 1072 "pending": [ "snipers" ], 1073 "complete": false, 1074 "proChecksLocked": 15, 1075 "fusion": { "available": true, "wallets": [], "walletsLocked": true }, 1076 "poweredBy": "DeFade.org" 1077}` 1078 }, 1079 { 1080 method:'GET', path:'/v1/token-price/:mint', desc:'Token price & market data', id:'token-price', 1081 tier:'free', 1082 detail:'Returns OHLCV candles, the latest price, the window's high and low and the percent change across it, all in USD. <code>?type=</code> picks the candle size, and with it how far back the window reaches: <code>15m</code> (default) covers about 2.5 days, <code>1H</code> about 10 days, <code>4H</code> about 40 days, <code>1D</code> up to a year â a token younger than the window returns candles from its first trade. Data sourced from DexScreener and on-chain DEX pools.', 1083 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'},{name:'type',type:'string',required:false,desc:'Candle size: <code>1m</code>, <code>5m</code>, <code>15m</code> (default), <code>30m</code>, <code>1H</code>, <code>4H</code> or <code>1D</code>. Any other value is rejected with 400.'}], 1084 fields:[ 1085 {n:'candles',t:'array',d:'OHLCV candles, oldest first: <code>ts</code> (ms), <code>open</code>, <code>high</code>, <code>low</code>, <code>close</code>, <code>volume</code> and the matching <code>*Usd</code> values.'}, 1086 {n:'current',t:'object',d:'Latest close, as <code>current.priceUsd</code>.'}, 1087 {n:'priceChange',t:'number',d:'Percent change from the first candle to the last across the requested window. Null when it cannot be computed.'}, 1088 {n:'high',t:'object',d:'Window high as <code>priceUsd</code> plus its <code>ts</code>. <code>low</code> is the same shape.'}, 1089 {n:'totalCandles',t:'number',d:'Number of candles returned. A token with no chart data answers <code>candles: []</code> and <code>totalCandles: 0</code>.'}, 1090 ], 1091 response:`{ 1092 "token": "7xK...", 1093 "timestamp": "2026-08-28T09:30:11.402Z", 1094 "candles": [ 1095 { "ts": 1756369200000, "open": 0.000071, "high": 0.000103, "low": 0.000068, "close": 0.000082, "volume": 25170 } 1096 ], 1097 "current": { "priceUsd": 0.000082 }, 1098 "priceChange": 9.64, 1099 "high": { "priceUsd": 0.000103, "ts": 1756370100000 }, 1100 "low": { "priceUsd": 0.000068, "ts": 1756369200000 }, 1101 "totalCandles": 96, 1102 "poweredBy": "DeFade.org" 1103}` 1104 }, 1105 { 1106 method:'GET', path:'/v1/holders/:mint', desc:'Holder distribution', id:'holders', 1107 tier:'free', 1108 detail:'Analyzes token holder distribution â top holder concentration, whale counts, and breakdown by wallet size. High concentration in top wallets is a common rug pull indicator.', 1109 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1110 fields:[ 1111 {n:'totalHolders',t:'number',d:'Holder count. This is a fast estimate from the top accounts \u2014 not an exhaustive census.'}, 1112 {n:'topHolders',t:'array',d:'Top 20 accounts: <code>rank</code>, <code>address</code> (the token account), <code>walletAddress</code> (its owner), <code>amount</code>, <code>percentage</code>, <code>solBalance</code>, plus <code>isProtocol</code> / <code>protocolLabel</code> / <code>protocolType</code> when the holder is a pool, locker, treasury or custodian rather than a person.'}, 1113 {n:'concentration',t:'object',d:'<code>top5</code>, <code>top10</code>, <code>top20</code> as percentages of supply, counting REAL wallets only \u2014 pools, lockers and other protocol accounts are excluded.'}, 1114 {n:'protocolHoldings',t:'object',d:'What was excluded: <code>count</code> and <code>totalPct</code>.'}, 1115 {n:'lockedSupply',t:'object',d:'<code>pct</code> plus a <code>lockers</code> array naming each escrow.'}, 1116 {n:'deferredUnlock',t:'object',d:'Supply locked now that unlocks back to the deployer later \u2014 <code>pct</code>, <code>unlockDate</code>, <code>cancelablePct</code>. Null when there is none. A scheduled overhang, not a burn.'}, 1117 {n:'bundles',t:'object',d:'Bundle detection over the real wallets: <code>detected</code>, <code>bundlePct</code>, <code>groups</code>.'}, 1118 ], 1119 response:`{ 1120 "token": "7xK...", 1121 "timestamp": "2026-08-28T09:30:11.402Z", 1122 "totalHolders": 412, 1123 "topHolders": [ 1124 { "rank": 1, "address": "CPd...", "walletAddress": "CPd...", "amount": 153040000, "percentage": "15.95", "isProtocol": true, "protocolLabel": "Pump.fun AMM", "protocolType": "amm" } 1125 ], 1126 "concentration": { "top5": 18.2, "top10": 26.9, "top20": 34.1 }, 1127 "protocolHoldings": { "count": 2, "totalPct": 30.01 }, 1128 "lockedSupply": { "pct": 0, "lockers": [] }, 1129 "deferredUnlock": null, 1130 "bundles": { "detected": false, "bundlePct": "0.00", "groups": [] }, 1131 "poweredBy": "DeFade.org" 1132}` 1133 }, 1134 { 1135 method:'GET', path:'/v1/liquidity/:mint', desc:'Liquidity pool depth', id:'liquidity', 1136 tier:'starter', 1137 detail:'Returns liquidity pool details across Raydium, Orca, and other Solana DEXs. Shows whether liquidity is locked or burnt â unlocked liquidity is a major rug pull risk factor.', 1138 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1139 fields:[ 1140 {n:'lpStatus',t:'string',d:'The headline verdict on the pool \u2014 e.g. BURNED, LOCKED, UNLOCKED, NO LP FOUND. <code>lpStatusColor</code> is the matching colour.'}, 1141 {n:'lpBurnPct',t:'number',d:'Percent of LP tokens burned; <code>lpLockPct</code> is the percent locked. <code>lpBurned</code> and <code>lpLocked</code> are the booleans behind them.'}, 1142 {n:'totalLiquidityUsd',t:'number',d:'Combined USD depth across pools. <code>pools</code> lists them individually and <code>poolCount</code> counts them.'}, 1143 {n:'poolLocks',t:'array',d:'Per-pool lock detail. <code>lpLockable</code> says whether this pool type can be locked at all, and <code>lpNote</code> explains the verdict in words.'}, 1144 {n:'dex',t:'string',d:'Which DEX holds the deepest pool. <code>lpMint</code> is the LP token mint, <code>pumpFunGraduated</code> whether it left the bonding curve.'}, 1145 {n:'risk',t:'string',d:'Liquidity risk label, with <code>riskColor</code>. <code>rugCheckScore</code> is the external RugCheck figure where available, and <code>lpEvidence</code> carries the on-chain evidence behind the verdict.'}, 1146 ], 1147 response:`{ 1148 "token": "7xK...", 1149 "timestamp": "2026-08-28T09:30:11.402Z", 1150 "lpStatus": "BURNED", 1151 "lpStatusColor": "green", 1152 "lpBurned": true, 1153 "lpLocked": false, 1154 "lpBurnPct": 100, 1155 "lpLockPct": 0, 1156 "poolCount": 1, 1157 "totalLiquidityUsd": 48210, 1158 "pools": [ { "dex": "PumpSwap", "liquidityUsd": 48210, "pairAddress": "CPd..." } ], 1159 "dex": "PumpSwap", 1160 "pumpFunGraduated": true, 1161 "risk": "LOW", 1162 "riskColor": "green", 1163 "poweredBy": "DeFade.org" 1164}` 1165 }, 1166 { 1167 method:'GET', path:'/v1/socials/:mint', desc:'Social links & metadata', id:'socials', 1168 tier:'starter', 1169 detail:'Returns the token\'s social media links, website, and verification status. Sourced from on-chain metadata and DexScreener.', 1170 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1171 fields:[
1172 {n:'twitter',t:'string',d:'Links found for the token, each null when absent: <code>twitter</code>, <code>telegram</code>, <code>website</code>, <code>discord</code>.'}, 1173 {n:'description',t:'string',d:'Token description from its metadata, and <code>metadataUri</code> the URI it came from.'}, 1174 {n:'pumpFunReplies',t:'number',d:'Reply count on the pump.fun page, where the token has one.'}, 1175 {n:'linkCount',t:'number',d:'How many of the social links resolved.'}, 1176 {n:'socialScore',t:'number',d:'Presence score built from those links, with <code>socialScoreColor</code>. It measures whether a project HAS socials, not whether they are real.'}, 1177 ], 1178 response:`{ 1179 "token": "7xK...", 1180 "timestamp": "2026-08-28T09:30:11.402Z", 1181 "twitter": "https://x.com/example", 1182 "telegram": null, 1183 "website": "https://example.xyz", 1184 "discord": null, 1185 "description": "the example token", 1186 "pumpFunReplies": 88, 1187 "metadataUri": "https://ipfs.io/ipfs/Qm...", 1188 "linkCount": 2, 1189 "socialScore": 60, 1190 "socialScoreColor": "yellow", 1191 "poweredBy": "DeFade.org" 1192}` 1193 }, 1194 { 1195 method:'GET', path:'/v1/whales/:mint', desc:'Whale wallet tracking', id:'whales', 1196 tier:'starter', 1197 detail:'Identifies wallets holding significant supply (>1%) and tracks their positions. Useful for monitoring large holder activity that could impact price.', 1198 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1199 fields:[ 1200 {n:'whales',t:'array',d:'Wallets holding a significant share, each with its address, balance, percentage of supply and any attribution label (notable wallet, dev-linked stash, CEX).'}, 1201 {n:'protocolAccounts',t:'array',d:'Pools, lockers, treasuries and custodial accounts held OUT of the whale list, named, so a pool vault is never reported as a whale.'}, 1202 {n:'summary',t:'object',d:'The counts and totals \u2014 how many whales and what share of supply they hold between them.'}, 1203 {n:'terminalUsage',t:'object',d:'Which trading terminals the whale cohort trades through.'}, 1204 ], 1205 response:`{ 1206 "token": "7xK...", 1207 "timestamp": "2026-08-28T09:30:11.402Z", 1208 "whales": [ 1209 { "address": "5yN...", "balance": 5200000, "pctSupply": 5.2, "label": null } 1210 ], 1211 "protocolAccounts": [ 1212 { "address": "CPd...", "label": "Pump.fun AMM", "pctSupply": 15.95 } 1213 ], 1214 "summary": { "whaleCount": 8, "whaleHoldingPct": 28.4 }, 1215 "terminalUsage": { "Photon": 3, "BullX": 2 }, 1216 "poweredBy": "DeFade.org" 1217}` 1218 }, 1219 { 1220 method:'GET', path:'/v1/bundles/:mint', desc:'Bundle & sniper detection', id:'bundles', 1221 tier:'starter', 1222 detail:'Detects coordinated buy transactions (bundles) where multiple wallets bought in the same block â a common manipulation technique used by developers to control supply while appearing decentralized.', 1223 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1224 fields:[ 1225 {n:'bundles',t:'array',d:'Detected bundles. Each carries the wallets that bought together, what they spent and what share of supply they took.'}, 1226 {n:'summary',t:'object',d:'The totals across those bundles \u2014 how many bundles, how many wallets, and the combined percentage of supply they hold.'}, 1227 ], 1228 response:`{ 1229 "token": "7xK...", 1230 "timestamp": "2026-08-28T09:30:11.402Z", 1231 "bundles": [ 1232 { "wallets": ["3kM...", "8pQ..."], "totalSol": 12.5, "pctSupply": 4.1 } 1233 ], 1234 "summary": { "bundleCount": 3, "bundledWallets": 12, "bundledPct": 8.4 }, 1235 "poweredBy": "DeFade.org" 1236}` 1237 }, 1238 { 1239 method:'GET', path:'/v1/insider-network/:mint', desc:'Insider wallet mapping', id:'insider-network', 1240 tier:'starter', 1241 detail:'Maps wallet clusters that share funding sources or exhibit coordinated behavior â indicating insider control. Uses on-chain fund flow analysis to detect wallets linked to the deployer or early investors.', 1242 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1243 fields:[ 1244 {n:'insiderCount',t:'number',d:'Wallets in the connected cohort, holding <code>insiderHoldingPct</code> of supply between them.'}, 1245 {n:'connections',t:'array',d:'The links themselves \u2014 wallet-to-wallet transfers that tie the cohort together. <code>connectionsTotal</code> is the count before truncation.'}, 1246 {n:'nodes',t:'array',d:'Graph nodes, and <code>clusters</code> the groups they fall into.'}, 1247 {n:'totalTransfers',t:'number',d:'Transfers behind the graph, moving <code>transferredPct</code> of supply. <code>totalConnections</code> counts the distinct links.'}, 1248 {n:'walletConnections',t:'object',d:'Per-wallet connection counts.'}, 1249 {n:'locked',t:'boolean',d:'Non-Pro keys receive <code>{ locked: true, reason: "pro_only", upgradeUrl, message }</code> INSTEAD of the fields above \u2014 check for it before reading the rest.'}, 1250 ], 1251 response:`{ 1252 "token": "7xK...", 1253 "timestamp": "2026-08-28T09:30:11.402Z", 1254 "insiderCount": 6, 1255 "insiderHoldingPct": 11.3, 1256 "totalConnections": 9, 1257 "totalTransfers": 14, 1258 "transferredPct": 6.8, 1259 "connections": [ { "from": "3kM...", "to": "8pQ...", "amount": 4100000 } ], 1260 "connectionsTotal": 9, 1261 "nodes": [ { "address": "3kM...", "pctSupply": 2.4 } ], 1262 "clusters": [ { "size": 4, "pctSupply": 8.1 } ], 1263 "poweredBy": "DeFade.org" 1264}` 1265 }, 1266 { 1267 method:'GET', path:'/v1/smart-money/:mint', desc:'Smart money signals', id:'smart-money', 1268 tier:'starter', 1269 detail:'Tracks wallets with a proven profitable track record to see whether they\'re buying or selling a given token. A strong indicator of informed market sentiment.', 1270 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1271 fields:[ 1272 {n:'wallets',t:'array',d:'The holders that were profiled, each classified as smart money, verified, experienced, active trader or retail, with its win rate.'}, 1273 {n:'activeBuys',t:'array',d:'Other tokens the smart wallets are currently buying.'}, 1274 {n:'summary',t:'object',d:'<code>analyzed</code>, <code>smartMoneyCount</code>, <code>verifiedCount</code>, <code>experiencedCount</code>, <code>activeTraderCount</code>, <code>retailCount</code>, <code>smartMoneyPct</code>, <code>retailPct</code>, <code>avgWinRate</code>, and a <code>signal</code> with its <code>signalColor</code>.'}, 1275 ], 1276 response:`{ 1277 "token": "7xK...", 1278 "timestamp": "2026-08-28T09:30:11.402Z", 1279 "wallets": [ 1280 { "address": "5yN...", "tier": "smart_money", "winRate": 68 } 1281 ], 1282 "activeBuys": [ { "mint": "9cR...", "buyers": 3 } ], 1283 "summary": { 1284 "analyzed": 20, "smartMoneyCount": 3, "verifiedCount": 1, "experiencedCount": 4, 1285 "activeTraderCount": 6, "retailCount": 6, "smartMoneyPct": 15, "retailPct": 30, 1286 "avgWinRate": 41, "signal": "MIXED", "signalColor": "yellow" 1287 }, 1288 "poweredBy": "DeFade.org" 1289}` 1290 }, 1291 { 1292 method:'GET', path:'/v1/snipers/:mint', desc:'Sniper detection', id:'snipers', 1293 tier:'starter', 1294 detail:'Detects wallets that bought in the very first blocks after liquidity was added â often bots or insiders with advance knowledge of the token launch.', 1295 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1296 fields:[ 1297 {n:'snipers',t:'array',d:'Wallets that bought inside the launch window, capped at 30 rows.'}, 1298 {n:'totalEarlyBuyers',t:'number',d:'How many were found in total. <code>windowSeconds</code> is the launch window used and <code>firstTxTime</code> the launch itself.'}, 1299 {n:'terminals',t:'object',d:'Which trading terminals the launch cohort came through; <code>activeTerminals</code> is who is trading it now.'}, 1300 {n:'reachedGenesis',t:'boolean',d:'Whether the walk reached the true first transaction. When false, <code>partial</code> is true and the long tail of small snipers may be missing \u2014 do not treat the count as authoritative.'}, 1301 {n:'migrationCrankersExcluded',t:'array',d:'Migration-crank MEV bots filtered out of the sniper set: infrastru
1301cture, not launch coordination. Named rather than silently dropped.'}, 1302 {n:'stats',t:'object',d:'Cohort totals for the window.'}, 1303 ], 1304 response:`{ 1305 "token": "7xK...", 1306 "timestamp": "2026-08-28T09:30:11.402Z", 1307 "snipers": [ { "address": "8pQ...", "buyBlock": 1, "holdingPct": 1.8 } ], 1308 "terminals": { "Photon": 4, "BullX": 2 }, 1309 "activeTerminals": { "Photon": 2 }, 1310 "totalEarlyBuyers": 23, 1311 "firstTxTime": 1756368000, 1312 "windowSeconds": 120, 1313 "reachedGenesis": true, 1314 "partial": false, 1315 "migrationCrankersExcluded": [], 1316 "stats": { "sniperPct": 6.4 }, 1317 "poweredBy": "DeFade.org" 1318}` 1319 }, 1320 { 1321 method:'GET', path:'/v1/dev-tracker/:mint', desc:'Developer wallet history', id:'dev-tracker', 1322 tier:'starter', 1323 detail:'Follows the creator\'s own position in THIS token: what they were minted or bought, what they sold into the pool, and what left the wallet another way \u2014 transferred out, locked in an escrow, seeded as liquidity, or parked at a known treasury or custodian \u2014 with the transactions behind each bucket. Those routes are separated on purpose: seeding a pool and locking supply both empty a dev wallet without being an exit, and a park at a custodial entity cannot be sold at all. It does NOT cover the creator\'s other launches \u2014 for previous tokens and rug history, see Deployer Reputation.', 1324 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1325 fields:[ 1326 {n:'status',t:'string',d:'One-line verdict. <code>STILL HOLDING</code>, <code>PARTIAL EXIT</code>, <code>FULLY EXITED</code>, <code>TRANSFERRED OUT</code>, <code>SOLD & TRANSFERRED</code>, <code>HOLDING + TRANSFERRED</code>, <code>DISTRIBUTED</code>, <code>LOCKED</code>, <code>HOLDING + LOCKED</code>, <code>LOCKED + TRANSFERRED</code>, <code>TRANSFERRED + LOCKED</code>, <code>SEEDED LIQUIDITY</code>, <code>TRANSFERRED TO TREASURY</code>, <code>HOLDING + TREASURY</code>, <code>PARKED AT CUSTODIAN</code>, <code>HOLDING + CUSTODIAL PARK</code>, <code>BURNED</code>, <code>SEEDED LIQUIDITY + BURNED</code>, <code>SOLD & BURNED</code>, <code>HOLDING + BURNED</code>, <code>INDEXING</code> (accounting incomplete, usually seconds after launch), <code>NOT TRACKED</code> (no balance and no transactions found), <code>NO TOKENS</code>, or <code>UNKNOWN CREATOR</code>.'}, 1327 {n:'statusColor',t:'string',d:'How to render the status: <code>green</code>, <code>yellow</code>, <code>gray</code> or <code>red</code>. Note a dev selling out is <code>gray</code>, not red \u2014 it is the standard memecoin launch pattern, not a rug signal.'}, 1328 {n:'creatorSource',t:'string',d:'How the dev wallet was identified: <code>creators_verified</code> / <code>creators</code> (signed creator metadata), <code>owner</code>, <code>mint_tx</code> (the mint-creation transaction), <code>launch_platform_payment</code> (a launch platform deployed the token and this wallet\u2019s on-chain payment launched it \u2014 see <code>launchPlatformCreator</code>) \u2014 or <code>authorities</code> / <code>mint_authority</code> / <code>freeze_authority</code>, which name whoever can edit the token rather than a person. <code>caller_supplied</code> means you named the wallet yourself. Null when no creator resolved.'}, 1329 {n:'creatorInferred',t:'boolean',d:'True when creatorSource does not identify a person \u2014 a launchpad stamps one authority across every token it mints, so treat the wallet as unconfirmed. False for a signed creator, for a caller-supplied wallet, and when no source is recorded.'}, 1330 {n:'walletBalance',t:'object|null',d:'The dev wallet\u2019s balance in the chain\u2019s own coin: <code>amount</code> (number) and <code>symbol</code> (<code>SOL</code>). <code>null</code> when the balance could not be read \u2014 never a zero.'}, 1331 {n:'currentHolding',t:'number',d:'Tokens the dev holds now, in whole tokens. <code>currentHoldingPct</code> is the same figure as a percentage of supply; <code>currentHoldingDisplay</code> is the display-safe string, which reads <code>"< 0.01"</code> for a dust balance rather than rounding it to zero.'}, 1332 {n:'totalMinted',t:'number',d:'Tokens minted STRAIGHT to the dev \u2014 the genesis allocation. Deliberately not counted as a buy: it cost nothing. Percentage in <code>totalMintedPct</code>.'}, 1333 {n:'totalBought',t:'number',d:'Tokens the dev acquired by buying. Percentage in <code>totalBoughtPct</code>.'}, 1334 {n:'totalSold',t:'number',d:'Tokens sold through a DEX. Percentage in <code>totalSoldPct</code>.'}, 1335 {n:'totalTransferred',t:'number',d:'Tokens sent wallet-to-wallet with no SOL coming back \u2014 the wallet-hopping bucket. Excludes locks, liquidity seeding, known treasuries and custodial parks, which get their own totals below.'}, 1336 {n:'totalBurned',t:'number',d:'Tokens the dev destroyed with an SPL Token / Token-2022 <code>Burn</code> instruction, read from the instruction itself (the enhanced parser reports these as transfers with no counterparty). Out of circulation: never a transfer, never scored. Percentage in <code>totalBurnedPct</code>; <code>
1336burnCount</code> and <code>recentBurns</code> alongside.'}, 1337 {n:'totalLocked',t:'number',d:'Tokens sent to a lock/vesting program (Streamflow, Jupiter Lock). Percentage in <code>totalLockedPct</code>; <code>lockDetails</code> carries up to 10 entries of <code>program</code>, <code>amount</code>, <code>unlockDate</code> and <code>unlocksToCreator</code> \u2014 a lock that pays back to the dev is a deferred overhang, not a burn.'}, 1338 {n:'totalLiquidity',t:'number',d:'Tokens seeded into a pool (LP or pool creation). Percentage in <code>totalLiquidityPct</code>.'}, 1339 {n:'liquidityLock',t:'object|null',d:'Raydium Burn & Earn locks on this token\u2019s liquidity; <code>null</code> when there are none. <code>positions[]</code>: <code>kind</code> (<code>clmm</code> position or <code>cpmm</code> LP), <code>source</code> (<code>dev_seed</code>, <code>launchlab_migration</code> or <code>other</code>, with <code>lockedBy</code>), <code>lockSignature</code>, <code>lockedAt</code>, <code>feeKeyMint</code>, <code>feeKeyHolder</code> (who collects that liquidity\u2019s trading fees now), <code>feeKeyHolderIsDev</code>, <code>feeKeyHolderIsPlatform</code>, <code>feeKeyHolderReceivedFromDev</code>; CPMM locks add <code>pool</code>, <code>lpMint</code>, <code>quoteMint</code>, <code>lpLocked</code>, <code>poolLockedPct</code> and, for a dev seed, <code>lockedSharePct</code> of the LP the dev received. <code>positionsLocked</code> / <code>positionsSeeded</code> count the dev\u2019s own seeds. <code>launchPlatform</code> names the Raydium LaunchLab platform of a graduated token (<code>name</code>, <code>web</code>, <code>feeWallet</code>, <code>nftWallet</code>; the <code>*SharePct</code> LP split is the platform\u2019s <em>current</em> config and may differ from the one this token graduated under). <code>feeClaims</code>: <code>count</code>, <code>sol</code>, <code>tokens</code>, <code>other</code> (by quote mint), <code>byClaimant[]</code>, <code>recent[]</code>, with <code>countIsFloor</code> when only the latest <code>parsed</code> claims were read. Informational, not scored.'}, 1340 {n:'launchPlatformCreator',t:'object|null',d:'Set when a launch platform\u2019s own wallet deployed the token (e.g. StonkFun, which mints, seeds and locks every token itself): <code>platform</code>, <code>platformWallet</code>, <code>resolved</code>. When resolved, the wallet reported here paid the platform for this launch: <code>paymentSignature</code>, <code>paidSol</code>, <code>paidAt</code>, <code>creationSignature</code>, and <code>evidence</code> tying the payment to this token (<code>dev_buy</code> \u2014 the platform delivered the dev buy to the payer; <code>fee_key</code> \u2014 the payer was given the creator fee key of its Burn & Earn lock). When not resolved, the platform wallet is reported as the dev and <code>reason</code> says why the payer could not be proven. Read from chain only.'}, 1341 {n:'launchPlatformWallets',t:'object',d:'Addresses on this response that a Raydium LaunchLab launch platform declares as its own wallets in its on-chain PlatformConfig, keyed by address: <code>name</code> (e.g. StonkFun), <code>roles</code> (<code>fee_wallet</code>, <code>nft_wallet</code> \u2014 the wallet that receives graduation LP fee keys) and up to five <code>platformConfigs</code>. Covers the dev wallet, fee-key holders, fee claimants and transfer / receive / buy counterparties. Empty object when none match. Informational, not scored.'}, 1342 {n:'totalTreasury',t:'number',d:'Tokens sent to a known treasury wallet. <code>totalCustodial</code> is the same idea for a known custodial entity (the key sits with a custodian, so the parcel cannot be sold). Percentages in <code>totalTreasuryPct</code> and <code>totalCustodialPct</code>.'}, 1343 {n:'transferRecipients',t:'number',d:'Distinct wallets that received a transfer. <code>topRecipientOfTransferredPct</code> is the largest single recipient\'s share OF THE TRANSFERRED amount, and <code>distributionShaped</code> is true when the transfers read as spreading the minted allocation rather than hopping a position.'}, 1344 {n:'transferRecipientAnalysis',t:'array',d:'What the large recipients DID with the tokens. Each entry: <code>address</code>, <code>amountPct</code>, <code>stillHeldPct</code>, <code>verdict</code> (<code>parked</code>, <code>sold</code>, <code>forwarded</code>, <code>cex</code>, <code>cex_deposit</code>, <code>custodial_entity</code>), a human-readable <code>line</code>, plus <code>entityLabel</code>, <code>cexName</code>, <code>sweptTo</code>, <code>farmParcels</code> and <code>farmParking</code>. Informational \u2014 it never changes the status. <code>transferRecipientLabels</code> lists any attribution names (e.g. a known KOL).'}, 1345 {n:'roundTripCount',t:'number',d:'Outbound transfers matched to an inbou
1345nd leg from the same counterparty at nearly the same amount \u2014 supply that went out and came straight back. Netted OUT of the buy and transfer buckets so it cannot inflate both sides. <code>totalRoundTrip</code> and <code>recentRoundTrips</code> carry the amounts and signatures.'}, 1346 {n:'sellCount',t:'number',d:'Transaction counts per bucket, alongside <code>buyCount</code>, <code>mintCount</code>, <code>transferCount</code>, <code>lockCount</code>, <code>liquidityCount</code>, <code>treasuryCount</code>, <code>custodialCount</code> and <code>burnCount</code>.'}, 1347 {n:'recentSells',t:'array',d:'The transactions behind each bucket, newest first, capped at 10 (5 for buys and mints): <code>amount</code>, the counterparty (<code>to</code> or <code>from</code>), <code>signature</code> and unix <code>timestamp</code>. Siblings: <code>recentBuys</code>, <code>recentMints</code>, <code>recentTransfers</code>, <code>recentLocks</code>, <code>recentLiquidity</code>, <code>recentTreasuryTransfers</code>, <code>recentCustodialTransfers</code>, <code>recentBurns</code> (no counterparty: a burn goes to nobody).'}, 1348 {n:'holdingPercentage',t:'number',d:'Aliases kept for older integrations, duplicating the <code>*Pct</code> fields: <code>holdingPercentage</code>, <code>soldPercentage</code>, <code>transferredPercentage</code>, <code>treasuryPercentage</code>, <code>custodialPercentage</code>. Prefer the <code>*Pct</code> names.'}, 1349 {n:'lastActivity',t:'number',d:'Unix seconds of the dev\u0027s most recent move of this token, across every bucket \u2014 sells, buys, mints, transfers, locks, liquidity, treasury and custodial parks, round trips included. Null when the wallet has never moved the token.'}, 1350 ], 1351 response:`{ 1352 "token": "7xK...", 1353 "timestamp": "2026-08-28T09:12:44.918Z", 1354 "status": "PARTIAL EXIT", 1355 "statusColor": "yellow", 1356 "creatorSource": "mint_tx", 1357 "creatorInferred": false, 1358 "currentHolding": 18400000, 1359 "currentHoldingPct": 1.84, 1360 "currentHoldingDisplay": "1.84", 1361 "totalMinted": 100000000, 1362 "totalMintedPct": 10, 1363 "totalBought": 0, 1364 "totalSold": 62000000, 1365 "totalSoldPct": 6.2, 1366 "totalTransferred": 19600000, 1367 "totalTransferredPct": 1.96, 1368 "totalLocked": 0, 1369 "totalLiquidity": 0, 1370 "totalTreasury": 0, 1371 "totalCustodial": 0, 1372 "totalBurned": 0, 1373 "sellCount": 7, 1374 "buyCount": 0, 1375 "mintCount": 1, 1376 "transferCount": 2, 1377 "burnCount": 0, 1378 "transferRecipients": 2, 1379 "topRecipientOfTransferredPct": 71.4, 1380 "distributionShaped": false, 1381 "transferRecipientLabels": [], 1382 "transferRecipientAnalysis": [ 1383 { 1384 "address": "5yN...", "amountPct": 1.4, "stillHeldPct": 100, 1385 "verdict": "parked", "line": "recipient parked, never moved", 1386 "entityLabel": null, "cexName": null, "sweptTo": null, 1387 "farmParcels": 0, "farmParking": false 1388 } 1389 ], 1390 "roundTripCount": 0, 1391 "recentSells": [ 1392 { "amount": 12000000, "to": "CPd...", "signature": "4vB...", "timestamp": 1756370000 } 1393 ], 1394 "recentTransfers": [ 1395 { "amount": 14000000, "to": "5yN...", "toLabel": null, "signature": "2xQ...", "timestamp": 1756371200 } 1396 ], 1397 "lastActivity": 1756371200, 1398 "poweredBy": "DeFade.org" 1399}` 1400 }, 1401 { 1402 method:'GET', path:'/v1/copy-traders/:mint', desc:'Copy-trading detection', id:'copy-traders', 1403 tier:'starter', 1404 detail:'Compares the token portfolios of the top holders and surfaces wallet pairs that hold many of the same other tokens, a signal of coordinated or copy-trading behaviour. Returns the pairs and an overlap percentage per pair.', 1405 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1406 fields:[ 1407 {n:'copyGroups',t:'array',d:'Groups of wallets that repeatedly trade the same tokens in the same order \u2014 the follower pattern.'}, 1408 {n:'summary',t:'object',d:'<code>totalCopiers</code> and the group totals. A token with fewer than 5 holders to profile answers with empty groups.'}, 1409 ], 1410 response:`{ 1411 "token": "7xK...", 1412 "timestamp": "2026-08-28T09:30:11.402Z", 1413 "copyGroups": [ 1414 { "leader": "5yN...", "followers": ["3kM...", "8pQ..."], "tokensShared": 4 } 1415 ], 1416 "summary": { "totalCopiers": 7 }, 1417 "poweredBy": "DeFade.org" 1418}` 1419 }, 1420 { 1421 method:'GET', path:'/v1/funding-origin/:mint', desc:'Funding origin by
1421KYC tier', id:'funding-origin', 1422 tier:'pro', 1423 detail:'Traces the top holders back to where their wallets were funded (centralized exchanges, swap services, bridges, mixers) and aggregates the supply by source and KYC tier. High unknown or mixer share is a coordination signal.', 1424 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1425 fields:[ 1426 {n:'origins',t:'array',d:'Where holder supply was funded from, as <code>{ name, share }</code>, biggest first \u2014 the exchanges and services behind the wallets.'}, 1427 {n:'tiers',t:'array',d:'The same supply grouped by tier of certainty, as <code>{ tier, share }</code>.'}, 1428 {n:'coveragePct',t:'number',d:'Share of supply actually attributed to a funding origin. <code>dexPct</code> (bought on an AMM, origin erased) and <code>bridgedPct</code> are real states but NOT attribution, so they are excluded from coverage rather than inflating it.'}, 1429 {n:'walletCount',t:'number',d:'Wallets resolved, with <code>resolvedCount</code> and <code>unknownCount</code>. <code>totalKnownSupply</code> and <code>unknownSupply</code> are the token amounts behind them.'}, 1430 {n:'risk',t:'object',d:'Risk verdict with its label and severity.'}, 1431 {n:'computedAt',t:'string',d:'When this was computed; <code>fromCache</code> says whether it was served from a stored result.'}, 1432 ], 1433 response:`{ 1434 "token": "7xK...", 1435 "timestamp": "2026-08-28T09:30:11.402Z", 1436 "origins": [ { "name": "Binance", "share": 22.4 }, { "name": "Coinbase", "share": 9.1 } ], 1437 "tiers": [ { "tier": "cex", "share": 31.5 }, { "tier": "dex_acquired", "share": 40.2 } ], 1438 "coveragePct": 31.5, 1439 "dexPct": 40.2, 1440 "bridgedPct": 0, 1441 "totalKnownSupply": 315000000, 1442 "unknownSupply": 284000000, 1443 "walletCount": 20, 1444 "resolvedCount": 12, 1445 "unknownCount": 8, 1446 "risk": { "label": "MIXED", "severity": 2 }, 1447 "computedAt": "2026-08-28T09:20:00.000Z", 1448 "fromCache": false, 1449 "poweredBy": "DeFade.org" 1450}` 1451 }, 1452 { 1453 method:'GET', path:'/v1/funding-graph/:mint', desc:'Cross-funding graph', id:'funding-graph', 1454 tier:'pro', 1455 detail:'Maps which top holders were funded by the same upstream wallet, drawing the SOL-funding relationships behind the buys. Distinct from the insider network (token transfers between holders), this is who paid for whom.', 1456 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1457 fields:[ 1458 {n:'nodes',t:'array',d:'Wallets in the funding graph, each with its label and share of supply.'}, 1459 {n:'edges',t:'array',d:'Funding relationships between them \u2014 who paid whom, and how much.'}, 1460 {n:'hubs',t:'array',d:'Wallets that funded several holders: the shape that distinguishes one operator behind many wallets from unrelated buyers.'}, 1461 {n:'stats',t:'object',d:'Graph totals \u2014 node and edge counts, and how much supply the graph covers.'}, 1462 {n:'computedAt',t:'string',d:'When this was computed; <code>fromCache</code> says whether it was served from a stored result.'}, 1463 ], 1464 response:`{ 1465 "token": "7xK...", 1466 "timestamp": "2026-08-28T09:30:11.402Z", 1467 "nodes": [ { "address": "3kM...", "pctSupply": 2.4, "label": null } ], 1468 "edges": [ { "from": "9qR...", "to": "3kM...", "lamports": 200000000 } ], 1469 "hubs": [ { "address": "9qR...", "funded": 6 } ], 1470 "stats": { "nodeCount": 21, "edgeCount": 18, "coveredPct": 14.2 }, 1471 "computedAt": "2026-08-28T09:20:00.000Z", 1472 "fromCache": false, 1473 "poweredBy": "DeFade.org" 1474}` 1475 }, 1476 { 1477 method:'GET', path:'/v1/sybil-cluster/:mint', desc:'Sybil band clustering', id:'sybil-cluster', 1478 tier:'pro', 1479 detail:'Collapses the cross-funding relationships into bands of wallets that behave as a single actor, excluding shared CEX, mixer, and bridge sources, and reports the combined supply each band controls. Surfaces concentration that per-wallet checks miss.', 1480 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1481 fields:[ 1482 {n:'bands',t:'array',d:'Wallet clusters banded by how strongly they look like one operator behind many addresses.'}, 1483 {n:'stats',t:'object',d:'Totals across the bands \u2014 wallets clustered and the supply they hold.'}, 1484 {n:'risk',t:'object',d:'Verdict for the token, with its label and severity.'}, 1485 {n:'computedAt',t:'string',d:'When this was computed; <code>fromCache</code> says whether it was served from a stored result.'}, 1486 ], 1487 response:`{ 1488 "token": "7xK...", 1489 "timestamp": "2026-08-28T09:30:11.402Z", 1490 "bands": [ { "band": "likely", "wallets": 6, "pctSupply": 7.4 } ], 1491 "stats": { "clustered": 9, "pctSupply": 9.8 }, 1492 "risk": { "label": "ELEVATED", "severity": 3 }, 1493 "computedAt": "2026-08-28T09:20:00.000Z", 1494 "fromCache": false, 1495 "poweredBy": "DeFade.org" 1496}` 1497 }, 1498 { 1499 method:'GET', path:'/v1/fee-fingerprint/:mint', desc:'Shared bot fee settings', id:'fee-fingerprint', 1500 tier:'pro', chain:'solana', 1501 detail:'Groups wallets whose transactions pin an identical compute-unit price (or Jito tip) \u2014 the settings an operator types into a trading bot, which ride along in every wallet that bot drives. This is a shared-CONFIGURATION link and nothing more: it carries no timing claim, is never counted as bundled supply, and two wallets can match days apart. Values most of the launch used are excluded as client defaults rather than reported; round values and groups confined to one short window are scored down, because the first is a number strangers pick independently and the second can be two bots in dynamic-fee mode hitting the same congestion. Computed by the bundle scan, so a token that has never had one answers <code>pending</code> rather than an empty result. Solana only.', 1502 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1503 fields:[ 1504 {n:'groups',t:'array',d:'One entry per fee setting shared by two or more wallets, strongest first. Each carries its <code>wallets</code>, the <code>supplyPct</code> they bought, a <code>confidence</code> of 0\u2013100 and the <code>reasons</code> behind it.'}, 1505 {n:'excluded',t:'array',d:'Fee values suppressed as client defaults \u2014 too common across the launch to link anyone \u2014 with the wallet count each covered.'}, 1506 {n:'stats',t:'object',d:'Population accounting: wallets seen, how many carried a readable fee setting, how many were linked, and how many set no priority fee at all.'}, 1507 {n:'pending',t:'boolean',d:'Present and <code>true</code> when no bundle scan has run for this token yet, with a <code>reason</code>. Means nothing has looked \u2014 not that nothing was found.'}, 1508 {n:'computedAt',t:'string',d:'When this result was read.'}, 1509 ], 1510 response:`{ 1511 "token": "7xK...", 1512 "timestamp": "2026-08-28T09:30:11.402Z", 1513 "groups": [ 1514 { 1515 "family": "cu_price", 1516 "value": "1487662", 1517 "walletCount": 3, 1518 "supplyPct": 1.6, 1519 "sides": ["buy", "sell"], 1520 "confidence": 80, 1521 "reasons": ["same compute-unit limit", "matches on buys and sells"] 1522 } 1523 ], 1524 "excluded": [ { "value": "100000", "walletCount": 16, "reason": "generic_default" } ], 1525 "stats": { "groupCount": 13, "linkedWalletCount": 9, "linkedSupplyPct": 3.4, "walletsNoFeeData": 40 }, 1526 "computedAt": "2026-08-28T09:20:00.000Z", 1527 "poweredBy": "DeFade.org" 1528}` 1529 }, 1530 { 1531 method:'GET', path:'/v1/bundles-pro/:mint', desc:'Bundle Detection', id:'bundles-pro', 1532 tier:'pro', 1533 detail:'Deep launch-window bundle analysis: Jito atomic bundles, multi-hop funding chains, fresh-wallet cluster
1533s, and identical-amount groups, with a disposition breakdown of whether each bundle sold, transferred, or still holds.', 1534 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1535 fields:[ 1536 {n:'bundles',t:'array',d:'Bundles with the deep-scan detail: the wallets, what they spent, what they still hold, and how they were funded.'}, 1537 {n:'hiddenBundleCount',t:'number',d:'Bundles the shallow v1 detector does not see \u2014 the reason this endpoint exists.'}, 1538 {n:'summary',t:'object',d:'Totals across the detected bundles.'}, 1539 ], 1540 response:`{ 1541 "token": "7xK...", 1542 "timestamp": "2026-08-28T09:30:11.402Z", 1543 "bundles": [ 1544 { "wallets": ["3kM...", "8pQ..."], "totalSol": 12.5, "pctSupply": 4.1, "stillHeldPct": 62 } 1545 ], 1546 "hiddenBundleCount": 2, 1547 "summary": { "bundleCount": 5, "bundledPct": 11.9 }, 1548 "poweredBy": "DeFade.org" 1549}` 1550 }, 1551 { 1552 method:'GET', path:'/v1/historical-bundles/:mint', desc:'Historical bundles', id:'historical-bundles', 1553 tier:'pro', 1554 detail:'Detects coordinated buys during post-launch volume spikes, not just the launch window. Finds days where volume spiked well above the rolling average and looks for bundled buying inside those windows.', 1555 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1556 fields:[ 1557 {n:'spikes',t:'array',d:'Windows after launch where coordinated buying reappeared \u2014 the accumulation a launch-window-only scan misses.'}, 1558 {n:'bundles',t:'array',d:'The bundles found inside those windows.'}, 1559 {n:'summary',t:'object',d:'Totals across the spikes and bundles.'}, 1560 ], 1561 response:`{ 1562 "token": "7xK...", 1563 "timestamp": "2026-08-28T09:30:11.402Z", 1564 "spikes": [ { "startedAt": 1756380000, "windowSeconds": 300, "wallets": 7, "pctSupply": 3.2 } ], 1565 "bundles": [ { "wallets": ["3kM...", "8pQ..."], "totalSol": 8.1, "pctSupply": 2.0 } ], 1566 "summary": { "spikeCount": 2, "bundledPct": 5.2 }, 1567 "poweredBy": "DeFade.org" 1568}` 1569 }, 1570 { 1571 method:'GET', path:'/v1/kol/:mint', desc:'Notable holders', id:'kol', 1572 tier:'free', 1573 detail:'Checks the token\u2019s current holders against a database of notable Solana wallets (KOLs, X traders and labelled wallets), returning which of them hold the token and how much. A holder snapshot, informational only, it does not affect the risk score.', 1574 params:[{name:':mint',type:'string',required:true,desc:'Solana token mint address (base58)'}], 1575 fields:[ 1576 {n:'kols',t:'array',d:'Notable wallets (KOLs, X traders and labelled wallets) holding or trading this token, each named from the tracked roster with its position.'}, 1577 {n:'summary',t:'object',d:'How many were found and what share of supply they hold between them.'}, 1578 ], 1579 response:`{ 1580 "token": "7xK...", 1581 "timestamp": "2026-08-28T09:30:11.402Z", 1582 "kols": [ { "name": "Ansem", "address": "GV6...", "pctSupply": 1.2, "xUrl": "https://x.com/blknoiz06" } ], 1583 "summary": { "kolCount": 1, "kolHoldingPct": 1.2 }, 1584 "poweredBy": "DeFade.org" 1585}` 1586 }, 1587 { 1588 method:'GET', path:'/v1/holder-overlap', desc:'Holder overlap across tokens', id:'holder-overlap', 1589 tier:'pro', 1590 detail:'For 1 to 3 token mints, finds the top holders of each and maps which other tokens those holders share. Returns nodes and edges for a force-directed graph. Pass the mints as a comma-separated query parameter.', 1591 params:[{name:'mints',type:'string (query)',required:true,desc:'1 to 3 comma-separated mint addresses, e.g. ?mints=MINT_A,MINT_B'}], 1592 fields:[ 1593 {n:'mints',t:'array',d:'The mints you asked about, echoed back. This endpoint takes 1\u20133 mints via <code>?mints=A,B,C</code>, so the envelope carries <code>mints</code> where every other endpoint carries <code>token</code>.'}, 1594 {n:'nodes',t:'array',d:'Tokens the shared holders also hold.'}, 1595 {n:'edges',t:'array',d:'How many holders each pair of tokens has in common.'}, 1596 {n:'stats',t:'object',d:'<code>inputTokens</code>, <code>totalHolders</code>, <code>sharedTokensFound</code>, <code>sharedTokensShown</code>, <code>elapsedMs</code>.'}, 1597 {n:'cached',t:'boolean',d:'Whether the result came from a stored computation.'}, 1598 ], 1599 response:`{ 1600 "mints": ["7xK...", "9cR..."], 1601 "timestamp": "2026-08-28T09:30:11.402Z", 1602 "nodes": [ { "mint": "DezX...", "symbol": "BONK", "sharedHolders": 6 } ], 1603 "edges": [ { "a": "7xK...", "b": "9cR...", "sharedHolders": 4 } ], 1604 "stats": { "inputTokens": 2, "totalHolders": 40, "sharedTokensFound": 31, "sharedTokensShown": 12, "elapsedMs": 2140 }, 1605 "cached": false, 1606 "poweredBy": "DeFade.org" 1607}` 1608 }, 1609 { 1610 method:'GET', path:'/v1/wallet-overlap', desc:'Wallets holding several tokens', id:'wallet-overlap', 1611 tier:'pro', 1612 detail:'For 2 to 3 token mints, finds the top holders of each and returns the wallets that hold two or more of them. A wallet counts on a token when it is a top holder there (rank given) or its portfolio carries the token at any size (rank null). Same graph payload as <code>holder-overlap</code>, with wallet nodes in place of shared-token nodes. Pass the mints as a comma-separated query parameter.', 1613 params:[{name:'mints',type:'string (query)',required:true,desc:'2 to 3 comma-separated mint addresses, e.g. ?mints=MINT_A,MINT_B'}], 1614 fields:[ 1615 {n:'mints',t:'array',d:'The mints you asked about, echoed back. Like <code>holder-overlap</code>, the envelope carries <code>mints</code> where every other endpoint carries <code>token</code>.'}, 1616 {n:'nodes',t:'array',d:'The input tokens (<code>type: input</code>) and the overlapping wallets (<code>type: wallet</code>), each wallet with <code>totalShared</code> (how many inputs it holds), a label where one is known, and <code>holdings</code> keyed by input mint with <code>rank</code> and <code>topHolder</code>.'}, 1617 {n:'edges',t:'array',d:'One edge per wallet and input it holds; <code>weight</code> 3 where the wallet is a top holder, 1 where it merely holds the token.'}, 1618 {n:'stats',t:'object',d:'<code>inputTokens</code>, <code>totalHolders</code>, <code>overlapWalletsFound</code>, <code>overlapWalletsShown</code>, <code>holdingAll</code>, <code>byCount</code>, <code>elapsedMs</code>.'}, 1619 {n:'cached',t:'boolean',d:'Whether the result came from a stored computation.'}, 1620 ], 1621 response:`{ 1622 "mints": ["7xK...", "9cR..."], 1623 "timestamp": "2026-09-30T01:30:11.402Z", 1624 "nodes": [ 1625 { "id": "7xK...", "type": "input", "symbol": "EX", "holderCount": 50, "position": 0 }, 1626 { "id": "HxhW...", "type": "wallet", "symbol": "HxhWâ¦4uEK", "name": "Ansem", "totalShared": 2, 1627 "holdings": { "7xK...": { "rank": 3, "topHolder": true }, "9cR...": { "rank": null, "topHolder": false } } } 1628 ], 1629 "edges": [ { "source": "HxhW...", "target": "7xK...", "weight": 3 }, { "source": "HxhW...", "target": "9cR...", "weight": 1 } ], 1630 "stats": { "inputTokens": 2, "totalHolders": 91, "overlapWalletsFound": 7, "overlapWalletsShown": 7, "holdingAll": 7, "byCount": { "2": 7 }, "elapsedMs": 2140 }, 1631 "cached": false, 1632 "poweredBy": "DeFade.org" 1633}` 1634 }, 1635 { 1636 method:'GET', path:'/v1/wallet-reputation/:wallet', desc:'Wallet reputation: cross-token rug history', id:'wallet-reputation', 1637 tier:'pro', 1638 detail:'Everything DeFade has recorded about ONE wallet across every token it scanned: the tokens it was flagged in, which of them later rugged, the role it played in each (bundle, insider, funding, sniper, fresh) and a tier verdict that mirrors the scoring engineâs own repeat-offender rule, so the endpoint never claims more than a scan does. Sightings are written as a side effect of scans, so a wallet no scan has flagged answers <code>UNKNOWN</code>: absence of evidence, not a clean bill of health. Read from the reputation ledger alone: no chain calls, one unit. The address is a wallet, not a mint; on an EVM chain pass <code>?chain=</code>, since a 0x wallet exists on every chain and each keeps its own record.', 1639 params:[{name:':wallet',type:'string',required:true,desc:'Wallet address: base58 on Solana, 0x on an EVM chain (with <code>?chain=</code>).'},{name:'chain',type:'string',required:false,desc:'<code>solana</code> (default) or an EVM chain id. The ledger is per chain.'}], 1640 fields:[ 1641 {n:'wallet',t:'string',d:'The wallet you asked about, echoed back. The envelope carries <code>wallet</code> and <code>chain</code> where token endpoints carry <code>token</code>.'}, 1642 {n:'tier',t:'string',d:'<code>REPEAT_OFFENDER</code>: an operator role (bundle, insider or funding) in at least one confirmed rug, or 3+ confirmed rugs in any role, under the ambient-breadth ceilings (a wallet flagged across 30+ tokens, or 10+ in a week, is infrastru
1642cture or a spraying bot, and its rug count is the platform death rate). <code>RUG_ASSOCIATED</code>: confirmed rugs, but not qualifying. <code>OBSERVED</code>: flagged by scans, no confirmed rug yet. <code>UNKNOWN</code>: never flagged by any scan.'}, 1643 {n:'tokensSeen',t:'number',d:'Distinct tokens a scan flagged this wallet in, on this chain. <code>recentTokensSeen</code> is the same over the last 7 days.'}, 1644 {n:'rugsSeen',t:'number',d:'Of those, the tokens whose price and liquidity later collapsed on-chain (the RUGGED / DEAD verdict). A high risk score alone never counts.'}, 1645 {n:'operatorRugsSeen',t:'number',d:'Confirmed rugs where the walletâs role there was bundle, insider or funding: a participant in the launch rather than a bystander who bought in.'}, 1646 {n:'labels',t:'array',d:'Every role ever attached to the wallet, the union over all sightings.'}, 1647 {n:'labelGlossary',t:'object',d:'One sentence per label present, from what the detector behind it measured: <code>bundle</code> bought in a same-slot launch cohort; <code>insider</code> a transfer or shared-funder link to another top holder from 48h before launch (not an allocation); <code>funding</code> shares a funding source with other flagged holders (it did not fund the token); <code>sniper</code> bought in the first 120 seconds; <code>fresh</code> under 7 days old.'}, 1648 {n:'sightings',t:'array',d:'Per-token record, newest first with rugged tokens ranked first, capped at 50: <code>mint</code>, <code>symbol</code>, <code>name</code>, <code>labels</code> (the roles on that token), <code>maxRugScore</code>, <code>rugOutcome</code>, <code>ruggedAt</code>, <code>firstSeen</code>, <code>lastSeen</code>. The counts above cover the full history regardless of the cap.'}, 1649 {n:'protocol',t:'object|null',d:'Set when the address is known protocol infrastructure (an AMM authority, router or vault) that appears in countless unrelated transactions; its rug count then tracks platform volume, not intent, and scoring excludes it.'}, 1650 {n:'fromCache',t:'boolean',d:'Whether the record came from the short server cache (a few minutes: sightings accrue as scans land).'}, 1651 ], 1652 response:`{ 1653 "wallet": "HxhW...", 1654 "chain": "solana", 1655 "timestamp": "2026-09-30T09:30:11.402Z", 1656 "available": true, 1657 "tier": "REPEAT_OFFENDER", 1658 "tokensSeen": 6, 1659 "recentTokensSeen": 1, 1660 "rugsSeen": 4, 1661 "operatorRugsSeen": 2, 1662 "labels": [ "bundle", "insider", "sniper" ], 1663 "labelGlossary": { "bundle": "Bought in a launch bundle: one of a cohort of wallets that bought in the same or adjacent slots at launch ...", "insider": "Holder Network link: ...", "sniper": "Bought within the first 120 seconds of launch ..." }, 1664 "firstSeen": "2026-07-02T14:03:51.000Z", 1665 "lastSeen": "2026-09-29T21:17:08.000Z", 1666 "sightings": [ 1667 { "mint": "7xK...", "symbol": "EX", "name": "Example", "labels": [ "bundle", "sniper" ], "maxRugScore": 78, 1668 "rugOutcome": true, "ruggedAt": "2026-08-14T02:11:40.000Z", "firstSeen": "2026-08-13T22:40:05.000Z", "lastSeen": "2026-08-13T23:10:12.000Z" } 1669 ], 1670 "protocol": null, 1671 "computedAt": "2026-09-30T09:30:11.398Z", 1672 "fromCache": false, 1673 "poweredBy": "DeFade.org" 1674}` 1675 }, 1676 { 1677 method:'GET', path:'/v1/trending', desc:'Trending tokens', id:'trending', 1678 tier:'free', 1679 detail:'The current Solana token feed, built from DexScreener boosts and search and filtered for real depth \u2014 stablecoins, wrapped and staked SOL are excluded. Cached for a few minutes, so it is near-real-time rather than live.', 1680 params:[{name:'category',type:'string',required:false,desc:'Which feed: trending (default), new, gainers, losers, traded, viewed'}], 1681 fields:[ 1682 {n:'trending',t:'array',d:'The feed, best first. Each token carries its <code>symbol</code>, <code>mint</code>, <code>priceUsd</code> and <code>volume24h</code>. Empty when the upstream feed is unavailable rather than absent.'}, 1683 {n:'timestamp',t:'string',d:'When the response was assembled.'}, 1684 ], 1685 response:`{ 1686 "timestamp": "2026-08-28T09:30:11.402Z", 1687 "trending": [ 1688 { "symbol": "EX", "mint": "7xK...", "priceUsd": 0.000082, "volume24h": 412000 }, 1689 { "symbol": "FOO", "mint": "9cR...", "priceUsd": 0.00131, "volume24h": 208000 } 1690 ], 1691 "poweredBy": "DeFade.org" 1692}` 1693 }, 1694 { 1695 method:'GET', path:'/v1/usage', desc:'Your API usage stats & credit balance', id:'usage', 1696 tier:'starter', 1697 detail:'Returns your current API key\'s usage statistics â today\'s request count, total lifetime requests, plan limits, and overage credit balance.', 1698 params:[], 1699 fields:[ 1700 {n:'tier',t:'string',d:'The tier this key is on.'}, 1701 {n:'limits',t:'object',d:'<code>perMinute</code>, <code>perDay</code>, <code>perMonth</code>. <code>perMonth</code> is null on grandfathered keys, which have no monthly ceiling.'}, 1702 {n:'usage',t:'object',d:'<code>today</code>, <code>total</code>, <code>thisPeriod</code>, <code>remainingThisPeriod</code>, <code>periodResetsAt</code>. The period figures are null wherever <code>limits.perMonth</code> is.'}, 1703 {n:'units',t:'object',d:'How metering works: one request is one unit, except the heaviest EVM modules. <code>heavyOnEvm</code> lists them and <code>heavyCost</code> gives their unit cost.'}, 1704 {n:'credits',t:'object',d:'Overage: <code>balance</code>, <code>overageEnabled</code>, <code>costPerRequest</code>.'}, 1705 ], 1706 response:`{ 1707 "tier": "starter", 1708 "limits": { "perMinute": 30, "perDay": 1000, "perMonth": 5000 }, 1709 "usage": { 1710 "today": 214, "total": 18402, "thisPeriod": 3120, 1711 "remainingThisPeriod": 1880, "periodResetsAt": "2026-09-12T00:00:00.000Z" 1712 }, 1713 "units": { "note": "Requests are metered in units. One request costs 1 unit, except the heaviest EVM modules which cost 5.", "heavyOnEvm": ["funding-origin"], "heavyCost": 5 }, 1714 "credits": { "balance": 0, "overageEnabled": false, "costPerRequest": 0.02 } 1715}` 1716 }, 1717]; 1718 1719// ======== HELPERS (must be defined before render) ======== 1720function syntaxHighlight(json) { 1721 return json 1722 .replace(/"([^"]+)":/g, '<span class="key-r">"$1"</span>:') 1723 .replace(/: "([^"]*)"/g, ': <span class="val-s">"$1"</span>') 1724 .replace(/: (\d+\.?\d*)/g, ': <span class="val-n">$1</span>') 1725 .replace(/: (true|false)/g, ': <span class="val-b">$1</span>'); 1726} 1727 1728// ======== RENDER ENDPOINTS ======== 1729const list = document.getElementById('endpoint-list'); 1730 1731// Build all HTML in one pass, then set innerHTML once â avoids the 1732// innerHTML += bug that strips onclick handlers from previously rendered nodes 1733const allHtml = endpoints.map((ep, i) => { 1734 const pathHtml = ep.path.replace(/:(\w+)/g, '<span class="param">:$1</span>'); 1735 // Since 2026-08-09 every paid plan reaches every endpoint â plans differ on 1736 // volume, rate limit and chains, not on which routes they can call â so the 1737 // per-endpoint plan badge names no distinction and reads the same on all 25. 1738 // ep.tier is kept on the data so the matrix can be reinstated if that changes. 1739 const tierTag = '<span class="tag tag-starter">Every plan</span>'; 1740 // Chain availability. Everything runs on Solana; SOLANA_ONLY is the one 1741 // endpoint with no EVM route of its own â EVM bundle analysis is a single 1742 // deep module that ships as bundles-pro (see the Chains section). 1743 const SOLANA_ONLY = ['bundles']; 1744 const CHAIN_AGNOSTIC = ['usage']; // reports on the key, not on a token 1745 const chainTag = CHAIN_AGNOSTIC.includes(ep.id) 1746 ? ''
1747 : SOLANA_ONLY.includes(ep.id) 1748 ? '<span class="tag tag-chain">Solana only</span>' 1749 : '<span class="tag tag-chain">All chains</span>'; 1750 1751 const paramsHtml = ep.params.length ? ` 1752 <div class="detail-section"> 1753 <div class="detail-label">Parameters</div> 1754 <div style="overflow-x:auto"> 1755 <table class="param-table"> 1756 <thead><tr><th>Name</th><th>Type</th><th>Required</th><th>Description</th></tr></thead> 1757 <tbody>${ep.params.map(p => ` 1758 <tr> 1759 <td class="param-name">${p.name}</td> 1760 <td class="param-type">${p.type}</td> 1761 <td>${p.required ? '<span class="required">Required</span>' : 'Optional'}</td> 1762 <td>${p.desc}</td> 1763 </tr>`).join('')} 1764 </tbody> 1765 </table> 1766 </div> 1767 </div>` : ''; 1768 1769 const fieldsHtml = ep.fields ? ` 1770 <div class="detail-section"> 1771 <div class="detail-label">Response Fields</div> 1772 <div style="overflow-x:auto"> 1773 <table class="field-table"> 1774 <thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead> 1775 <tbody>${ep.fields.map(f => ` 1776 <tr> 1777 <td class="fname">${f.n}</td> 1778 <td class="ftype">${f.t}</td> 1779 <td>${f.d}</td> 1780 </tr>`).join('')} 1781 </tbody> 1782 </table> 1783 </div> 1784 </div>` : ''; 1785 1786 const responseHtml = ep.response ? ` 1787 <div class="detail-section"> 1788 <div class="detail-label">Example Response</div> 1789 <div class="response-example">${syntaxHighlight(ep.response)}</div> 1790 </div>` : ''; 1791 1792 return ` 1793 <div class="endpoint" id="ep-${ep.id || i}"> 1794 <div class="endpoint-header" data-toggle="ep-${ep.id || i}"> 1795 <span class="method-badge method-get">${ep.method}</span> 1796 <span class="endpoint-path">${pathHtml}</span> 1797 ${tierTag} 1798 ${chainTag} 1799 <span class="endpoint-desc">${ep.desc}</span> 1800 <span class="endpoint-chevron">â¼</span> 1801 </div> 1802 <div class="endpoint-detail"> 1803 <div class="detail-desc">${ep.detail || ''}</div> 1804 ${paramsHtml} 1805 ${fieldsHtml} 1806 ${responseHtml} 1807 </div> 1808 </div>`; 1809}).join(''); 1810 1811list.innerHTML = allHtml; 1812 1813// ======== SIDEBAR ENDPOINT LINKS ======== 1814// The sidebar named four endpoints as #analyze, #rug-score, #token-price and 1815// #holders, but the cards render as #ep-analyze and so on, so all four were 1816// dead: clicking them did nothing. Alongside them "+ 9 more endpoints" pointed 1817// at #more-endpoints, which has never existed, and said 9 when the list had 1818// grown to 22. Both counts below are derived rather than typed, so neither can 1819// go stale again. 1820const namedEndpointLinks = [...document.querySelectorAll('.sidebar-link[href^="#ep-"]')]; 1821const moreLink = document.getElementById('more-endpoints-link'); 1822if (moreLink) { 1823 const namedIds = new Set(namedEndpointLinks.map(a => a.getAttribute('href').slice(4))); 1824 const remaining = endpoints.filter(ep => !namedIds.has(ep.id)); 1825 moreLink.textContent = `+ ${remaining.length} more endpoints`; 1826 // Land on the first endpoint the sidebar does NOT name â that is what the 1827 // label promises. Falls back to the section when every one is listed. 1828 if (remaining.length > 0) moreLink.setAttribute('href', `#ep-${remaining[0].id}`); 1829} 1830 1831// A sidebar link to an endpoint should OPEN it, not drop the reader on a 1832// collapsed header â landing on a closed accordion is barely better than the 1833// dead link this replaces. Also runs on load, so a shared #ep-⦠URL opens the 1834// card it points at. 1835function openEndpointFromHash(hash) { 1836 if (!hash || hash.indexOf('#ep-') !== 0) return; 1837 const el = document.getElementById(hash.slice(1)); 1838 if (el) el.classList.add('open'); 1839} 1840window.addEventListener('hashchange', () => openEndpointFromHash(location.hash)); 1841openEndpointFromHash(location.hash); 1842 1843// ======== INTERACTIONS ======== 1844// Use event delegation â one listener on the parent, works for all endpoints 1845list.addEventListener('click', (e) => { 1846 const header = e.target.closest('[data-toggle]'); 1847 if (!header) return; 1848 const id = header.getAttribute('data-toggle'); 1849 const el = document.getElementById(id); 1850 if (el) el.classList.toggle('open'); 1851}); 1852 1853// Keep toggleEndpoint for any legacy direct calls 1854function toggleEndpoint(id) { 1855 const el = document.getElementById(id); 1856 if (el) el.classList.toggle('open'); 1857} 1858 1859function switchTab(groupId, activeId, el) { 1860 const tabs = document.querySelectorAll(`#${groupId} .code-tab`); 1861 const blocks = document.querySelectorAll(`.code-block[data-group="${groupId}"]`);
1862 tabs.forEach(t => t.classList.remove('active')); 1863 blocks.forEach(b => b.classList.remove('active')); 1864 document.getElementById(activeId).classList.add('active'); 1865 el.classList.add('active'); 1866} 1867 1868function copyBlock(btn, blockId) { 1869 const block = document.getElementById(blockId); 1870 const pre = block.querySelector('pre'); 1871 const text = pre ? pre.textContent : block.textContent; 1872 navigator.clipboard.writeText(text.trim()).then(() => { 1873 btn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>'; 1874 btn.classList.add('copied'); 1875 setTimeout(() => { btn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'; btn.classList.remove('copied'); }, 2000); 1876 }); 1877} 1878 1879// Sidebar active state 1880const sidebarLinks = document.querySelectorAll('.sidebar-link'); 1881const sections = document.querySelectorAll('section[id]'); 1882function updateActive() { 1883 let current = ''; 1884 sections.forEach(s => { 1885 if (window.scrollY >= s.offsetTop - 100) current = s.id; 1886 }); 1887 sidebarLinks.forEach(l => { 1888 l.classList.toggle('active', l.getAttribute('href') === '#' + current); 1889 }); 1890} 1891window.addEventListener('scroll', updateActive); 1892updateActive(); 1893 1894// Mobile: close sidebar when clicking a link 1895sidebarLinks.forEach(link => { 1896 link.addEventListener('click', () => { 1897 openEndpointFromHash(link.getAttribute('href')); 1898 const sidebar = document.getElementById('sidebar'); 1899 const overlay = document.getElementById('sidebar-overlay'); 1900 if (window.innerWidth <= 900) { 1901 sidebar.classList.remove('open'); 1902 if (overlay) overlay.classList.remove('open'); 1903 } 1904 }); 1905}); 1906</script>
1906 1907
1907<script src="/js/auth.js" defer></script>
vendor: 1 bytes, line 1907
1907
1908<script> 1909// EVM beta pricing reveal â same gate as the site. Public gets 1910// enabled:false and this page renders exactly as before. 1911(function(){ 1912 var API_ORIGIN = (window.location.hostname === 'localhost') ? '' : 'https://api.defade.org'; 1913 // Price + crypto-product matrix, scope x period. These strings must track 1914 // STRIPE_PRICES in server.js and CRYPTO_PRODUCTS in routes/crypto-pay.js â 1915 // the same three numbers live in developers.html too, which is why the two 1916 // pages are worth diffing whenever pricing moves. 1917 var DOCS_PRICES = { 1918 // Solana-only plans retired 2026-08-22 â all-chains is the only family. 1919 all: { 1920 suffix: '_all', 1921 monthly: { lite: '$29', starter: '$99', growth: '$199', pro: '$399', ent: '$1,999', per: '/mo' }, 1922 yearly: { lite: '$278', starter: '$950', growth: '$1,910', pro: '$3,830', ent: '$19,190', per: '/yr' }, 1923 crypto: { 1924 monthly: { lite: 'api_lite_all_monthly', starter: 'api_starter_all_monthly', growth: 'api_growth_all_monthly', pro: 'api_pro_all_monthly', ent: 'api_enterprise_all_monthly' }, 1925 yearly: { lite: 'api_lite_all_yearly', starter: 'api_starter_all_yearly', growth: 'api_growth_all_yearly', pro: 'api_pro_all_yearly', ent: 'api_enterprise_all_yearly' } 1926 } 1927 } 1928 }; 1929 var docsScope = 'all'; // all-chains only since 2026-08-22 1930 var docsPeriod = 'monthly'; 1931 1932 // DOCS_PRICES above is the offline fallback only. The live numbers come from 1933 // GET /api/pricing, derived from the same API_TIERS / STRIPE_PRICES the 1934 // checkout charges against â this page holding its own copy is why it was 1935 // still quoting $29/$99/$499 the day after the 2026-08-09 reprice. 1936 (function loadLiveDocsPricing(){ 1937 var usd = function(n){ return '$' + Number(n).toLocaleString('en-US'); }; 1938 var KEY = { lite: 'lite', starter: 'starter', growth: 'growth', pro: 'pro', enterprise: 'ent' }; 1939 fetch(API_ORIGIN + '/api/pricing') 1940 .then(function(r){ return r.ok ? r.json() : null; }) 1941 .then(function(data){ 1942 if (!data || !Array.isArray(data.plans) || !data.plans.length) return; 1943 var next = { 1944 solana: { suffix: '', monthly: { per: '/mo' }, yearly: { per: '/yr' }, crypto: { monthly: {}, yearly: {} } }, 1945 all: { suffix: '_all', monthly: { per: '/mo' }, yearly: { per: '/yr' }, crypto: { monthly: {}, yearly: {} } }, 1946 }; 1947 data.plans.forEach(function(p){ 1948 var scope = p.chainScope === 'all' ? 'all' : 'solana'; 1949 var k = KEY[p.tier.replace(/_all$/, '')]; 1950 if (!k) return; 1951 next[scope].monthly[k] = usd(p.monthly); 1952 next[scope].yearly[k] = usd(p.yearly); 1953 next[scope].crypto.monthly[k] = p.crypto.monthly; 1954 next[scope].crypto.yearly[k] = p.crypto.yearly; 1955 }); 1956 // Only adopt a complete payload; a partial one would blank a card. 1957 // Only the 'all' scope is sold since 2026-08-22. 1958 var complete = ['lite','starter','growth','pro','ent'].every(function(k){ return next.all.monthly[k] && next.all.crypto.monthly[k]; }); 1959 if (!complete) return; 1960 DOCS_PRICES = next; 1961 renderDocsPrices(); 1962 }) 1963 .catch(function(){ /* offline â the fallback is already rendered */ }); 1964 })(); 1965 1966 function renderDocsPrices(){ 1967 var p = DOCS_PRICES[docsScope]; 1968 var amounts = p[docsPeriod]; 1969 var cryptoIds = p.crypto[docsPeriod]; 1970 [['docsLiteAmt','docsLiteCrypto','lite'], 1971 ['docsStarterAmt','docsStarterCrypto','starter'], 1972 ['docsGrowthAmt','docsGrowthCrypto','growth'], 1973 ['docsProAmt','docsProCrypto','pro'], 1974 ['docsEntAmt','docsEntCrypto','ent']].forEach(function(r){ 1975 var amt = document.getElementById(r[0]); 1976 var crypto = document.getElementById(r[1]); 1977 if (amt) amt.innerHTML = amounts[r[2]] + ' <span>' + amounts.per + '</span>'; 1978 if (crypto) crypto.href = '/crypto-checkout?product=' + cryptoIds[r[2]]; 1979 }); 1980 } 1981 function paintToggle(sel, attr, value){ 1982 document.querySelectorAll(sel).forEach(function(b){ 1983 var active = b.dataset[attr] === value; 1984 b.style.background = active ? 'var(--accent)' : 'transparent'; 1985 b.style.color = active ? 'var(--bg-primary)' : 'var(--text-primary)'; 1986 }); 1987 } 1988 window.setDocsScope = function(scope){ 1989 docsScope = (scope === 'all') ? 'all' : 'solana';
1990 paintToggle('#docsChainScope button', 'scope', docsScope); 1991 renderDocsPrices(); 1992 }; 1993 window.setDocsBilling = function(period){ 1994 docsPeriod = (period === 'yearly') ? 'yearly' : 'monthly'; 1995 paintToggle('#docsBilling button', 'period', docsPeriod); 1996 renderDocsPrices(); 1997 }; 1998 // Card checkout, same endpoint and payload the developers page posts. The 1999 // server resolves the price from the tier name, so the _all suffix is the 2000 // only thing that has to be right here. 2001 window.docsSubscribe = async function(tier, btn){ 2002 var label = btn ? btn.textContent : ''; 2003 if (btn) { btn.textContent = 'Redirectingâ¦'; btn.disabled = true; } 2004 // Mode 'change_plan' = this account already pays for an API plan by 2005 // card; the same key moves to this plan after a confirm. 2006 var post = function(confirmPlanChange){ 2007 return fetch(API_ORIGIN + '/api/stripe/checkout', { 2008 method: 'POST', 2009 credentials: 'include', 2010 headers: { 'Content-Type': 'application/json' }, 2011 body: JSON.stringify({ 2012 tier: (tier === 'ent' ? 'enterprise' : tier) + DOCS_PRICES[docsScope].suffix, 2013 period: docsPeriod, 2014 label: 'api-docs-subscribe', 2015 confirmPlanChange: confirmPlanChange 2016 }) 2017 }).then(function(r){ return r.json(); }); 2018 }; 2019 try { 2020 var data = await post(false); 2021 if (data.mode === 'change_plan') { 2022 if (!window.confirm(data.confirmMessage)) { 2023 if (btn) { btn.textContent = label; btn.disabled = false; } 2024 return; 2025 } 2026 if (btn) btn.textContent = 'Changing planâ¦'; 2027 data = await post(true); 2028 if (data.ok) { alert(data.message); window.location.href = '/dashboard'; return; } 2029 // 3-D Secure: Stripe's page takes the approval; the change applies when it clears. 2030 if (data.mode === 'authenticate' && data.url) { alert(data.message); window.location.href = data.url; return; } 2031 } 2032 if (data.url) { window.location.href = data.url; return; } 2033 alert(data.error || 'Failed to start checkout'); 2034 } catch (e) { 2035 alert('Network error. Please try again.'); 2036 } 2037 if (btn) { btn.textContent = label; btn.disabled = false; } 2038 }; 2039 renderDocsPrices(); 2040 // Chain lists are never hardcoded in the copy: /api/evm/access is the single 2041 // source of truth and already honours HIDDEN_CHAINS, so a chain that is held 2042 // back (BNB, at time of writing) can't leak into the docs, and one that 2043 // launches appears here with no edit. The markup ships a sensible default so 2044 // the page still reads correctly if the probe fails. 2045 var CHAIN_TICKER = { ethereum:'ETH', base:'BASE', robinhood:'RH', bsc:'BNB' }; 2046 var CHAIN_NAME = { ethereum:'Ethereum', base:'Base', robinhood:'Robinhood Chain', bsc:'BNB Chain' }; 2047 try { 2048 fetch(API_ORIGIN + '/api/evm/access', { credentials: 'include' }) 2049 .then(function(r){ return r.ok ? r.json() : null; }) 2050 .then(function(d){ 2051 if (!d || !d.enabled) return; 2052 var t = document.getElementById('docsChainScope'); 2053 if (t) t.style.display = 'flex'; 2054 var live = (d.chains || []).filter(function(c){ return CHAIN_TICKER[c]; }); 2055 if (!live.length) return; 2056 document.querySelectorAll('.chain-ticker-list').forEach(function(el){ 2057 el.textContent = ['SOL'].concat(live.map(function(c){ return CHAIN_TICKER[c]; })).join('·'); 2058 }); 2059 document.querySelectorAll('.chain-name-list').forEach(function(el){ 2060 el.textContent = live.map(function(c){ return CHAIN_NAME[c]; }).join(', '); 2061 }); 2062 document.querySelectorAll('.chain-id-rows').forEach(function(el){ 2063 el.innerHTML = live.map(function(c){ 2064 return '<tr><td class="param-name">' + c + '</td><td>' + CHAIN_NAME[c] + 2065 '</td><td><code>0x</code> + 40 hex characters</td></tr>'; 2066 }).join(''); 2067 }); 2068 }).catch(function(){}); 2069 } catch(e){} 2070})(); 2071</script>
2071 2072</body> 2073</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.