API Documentation

    MemeScout API

    Integrate real-time radar signals into your trading tools, bots, and applications.

    Quick Start

    1

    Get your API key

    Go to your Account Settings and generate an API key. API access requires Degen or Chad tier.

    2

    Add the Authorization header

    Include your API key in every request using the Authorization header.

    Authorization: Bearer smr_your_api_key_here
    3

    Make your first request

    Call the /signals endpoint to get current radar signals.

    Base URL

    https://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/api

    Endpoints

    GET
    /signals

    Returns current radar signals (active tokens on radar).

    Query Parameters

    ParameterTypeDefaultDescription
    min_scoreinteger0Minimum radar score (0-100)
    min_liquidityinteger0Minimum liquidity in USD
    max_age_minutesinteger240Maximum token age in minutes
    limitinteger50Max results (max: 100)

    Response

    {
      "success": true,
      "timestamp": "2026-01-28T15:00:00Z",
      "count": 12,
      "signals": [
        {
          "address": "ABC123...",
          "name": "TokenName",
          "symbol": "TKN",
          "radar_score": 82,
          "market_cap": 148000,
          "liquidity": 12400,
          "volume_5m": 22100,
          "volume_15m": 41800,
          "volume_1h": 85000,
          "buys": 24,
          "sells": 9,
          "price": 0.000148,
          "age_minutes": 42,
          "trigger_reason": "High volume + strong buy pressure",
          "risk_level": "Low",
          "risk_score": 250,
          "first_seen": "2026-01-28T14:18:00Z",
          "last_seen": "2026-01-28T15:00:00Z",
          "is_new": true,
          "is_returning": false,
          "is_recovered": false,
          "is_dropped": false,
          "data_source": "live",
          "top_10_holders_pct": 42.5,
          "creator_holds_pct": 3.2,
          "lp_burned": true,
          "lp_locked": false,
          "mint_authority_revoked": true,
          "freeze_authority_revoked": true,
          "is_mutable": false,
          "top3_holders_pct": 18.1,
          "lp_health_score": 72,
          "volume_consistency": 85,
          "wallet_risk_score": 68,
          "time_to_peak_estimate": "fast"
        }
      ]
    }
    GET
    /token/:address

    Returns detailed data for a specific token by its address.

    Response

    {
      "success": true,
      "token": {
        "address": "ABC123...",
        "name": "TokenName",
        "symbol": "TKN",
        "website": "https://...",
        "twitter": "@handle",
        "image": "https://...",
        "current": {
          "price": 0.000148,
          "market_cap": 148000,
          "liquidity": 12400,
          "volume_5m": 22100,
          "volume_15m": 41800,
          "volume_1h": 85000,
          "buys": 24,
          "sells": 9,
          "holders": 156,
          "radar_score": 82,
          "data_source": "live"
        },
        "radar": {
          "first_seen": "2026-01-28T14:18:00Z",
          "first_call_mc": 95000,
          "peak_mc": 180000,
          "trigger_reason": "High volume + strong buy pressure"
        },
        "risk": {
          "level": "Low",
          "score": 250,
          "lp_warning": null,
          "top_10_holders_pct": 42.5,
          "creator_holds_pct": 3.2,
          "lp_burned": true,
          "lp_locked": false,
          "mint_authority_revoked": true,
          "freeze_authority_revoked": true,
          "is_mutable": false,
          "top3_holders_pct": 18.1
        },
        "intelligence": {
          "lp_health_score": 72,
          "volume_consistency": 85,
          "wallet_risk_score": 68,
          "time_to_peak_estimate": "fast"
        }
      }
    }
    GET
    /calls
    New

    Returns historical radar calls with performance metrics. Query by date or last N days.

    Query Parameters

    ParameterTypeDefaultDescription
    datestring-Specific date (YYYY-MM-DD)
    daysinteger7Days to look back (ignored if date provided)
    limitinteger100Max results (max: 500)
    min_multipliernumber0Minimum peak multiplier (e.g., 2 = 2x)

    Response

    {
      "success": true,
      "timestamp": "2026-01-28T15:00:00Z",
      "period": {
        "start": "2026-01-21",
        "end": "2026-01-28"
      },
      "total_calls": 156,
      "calls": [
        {
          "address": "ABC123...",
          "name": "PepeGPT",
          "symbol": "PGPT",
          "image": "https://...",
          "call_date": "2026-01-28",
          "first_seen": "2026-01-28T14:18:00Z",
          "first_call_mc": 95000,
          "peak_mc": 285000,
          "multiplier": 3.0,
          "radar_score": 82,
          "trigger_reason": "High volume + strong buy pressure",
          "risk_level": "Low",
          "risk_score": 250
        }
      ]
    }
    GET
    /status

    Health check and usage statistics for your API key.

    Response

    {
      "success": true,
      "api_version": "1.0",
      "key_name": "ClawdBot",
      "requests_today": 142,
      "requests_total": 5840,
      "daily_limit": 10000,
      "tier": "degen"
    }

    Rate Limits

    TierRequests/MinuteRequests/Day
    Degen (Pro)10010,000
    Chad (Enterprise)20050,000

    When rate limited, you'll receive a 429 status code. Wait for the specified retry period before making more requests.

    Error Responses

    401

    unauthorized

    Invalid or missing API key

    403

    forbidden

    API access requires Degen or Chad tier

    403

    subscription_expired

    Your subscription has expired

    429

    rate_limited

    Rate limit exceeded. Try again later.

    404

    not_found

    Endpoint or resource not found

    Code Examples

    import requests
    
    API_KEY = "smr_your_api_key_here"
    BASE_URL = "https://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/api"
    
    headers = {"Authorization": f"Bearer {API_KEY}"}
    
    # Get current signals
    response = requests.get(f"{BASE_URL}/signals", headers=headers)
    signals = response.json()
    
    for signal in signals["signals"]:
        print(f"{signal['symbol']}: Score {signal['radar_score']}, MC ${signal['market_cap']:,.0f}")
    
    # Get historical calls (last 7 days, 2x+ multiplier)
    response = requests.get(
        f"{BASE_URL}/calls",
        headers=headers,
        params={"days": 7, "min_multiplier": 2}
    )
    calls = response.json()
    
    for call in calls["calls"]:
        print(f"{call['symbol']}: {call['multiplier']:.1f}x (${call['first_call_mc']:,} → ${call['peak_mc']:,})")

    WebSocket (Real-Time)
    New

    Connections are not persistent

    WebSocket connections run on serverless edge infrastructure and will disconnect — due to inactivity timeouts, heartbeat failures, or platform-level restarts. Your client must implement auto-reconnect with exponential backoff. Use the example below as a starting point.

    Connection

    Connect to the WebSocket endpoint for real-time radar signals. Authenticate using your API key as a query parameter.

    wss://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/ws?api-key=smr_your_key

    Events

    EventDirectionDescription
    connectedServer → ClientSent on successful connection
    signal_newServer → ClientNew token added to radar (full payload). Also fired when a previously hidden token re-appears.
    signal_updateServer → ClientSignal score/reason/tier changed (full enriched payload, same schema as signal_new)
    signal_removedServer → ClientToken removed from radar
    snapshotServer → ClientSent automatically on connect — contains all active signals so you catch up on anything missed during disconnects
    pingServer → ClientHeartbeat every 30s
    pongClient → ServerClient must respond to pings
    replayClient → ServerRequest a fresh snapshot of all active signals on demand

    signal_new Payload

    {
      "event": "signal_new",
      "timestamp": 1707928800000,
      "data": {
        "address": "ABC123...",
        "name": "PepeGPT",
        "symbol": "PGPT",
        "radar_score": 82,
        "market_cap": 148000,
        "liquidity": 12400,
        "volume_5m": 22100,
        "volume_1h": 85000,
        "buys": 24,
        "sells": 9,
        "price": 0.000148,
        "holders": 156,
        "age_minutes": 0,
        "trigger_reason": "High volume + strong buy pressure",
        "risk_level": "Low",
        "risk_score": 250,
        "lp_health_score": 72,
        "volume_consistency": 85,
        "wallet_risk_score": 68,
        "time_to_peak_estimate": "fast",
        "first_seen": "2026-02-14T12:00:00Z",
        "data_source": "live"
      }
    }

    Connection Example — JavaScript (with auto-reconnect)

    const WS_URL = "wss://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/ws?api-key=smr_your_key";
    const MAX_BACKOFF_MS = 30_000;
    
    function connect(attempt = 0) {
      const ws = new WebSocket(WS_URL);
    
      ws.onopen = () => {
        console.log("Connected to MemeScout Radar");
        attempt = 0; // reset backoff on success
        // Snapshot is sent automatically — no need to request it
      };
    
      ws.onmessage = (event) => {
        const msg = JSON.parse(event.data);
        switch (msg.event) {
          case "snapshot":
            console.log(`Snapshot: ${msg.data.count} active signals`);
            msg.data.signals.forEach(s => console.log(`  ${s.symbol} | Score: ${s.radar_score}`));
            break;
          case "signal_new":
            console.log("New signal:", msg.data.symbol, "Score:", msg.data.radar_score);
            break;
          case "signal_update":
            console.log("Updated:", msg.data.symbol, "→ Score:", msg.data.radar_score);
            break;
          case "signal_removed":
            console.log("Removed:", msg.data.address);
            break;
          case "ping":
            ws.send(JSON.stringify({ event: "pong" }));
            break;
        }
      };
    
      ws.onclose = (e) => {
        const delay = Math.min(1000 * 2 ** attempt, MAX_BACKOFF_MS);
        console.warn(`Disconnected (${e.code}: ${e.reason}). Reconnecting in ${delay}ms...`);
        setTimeout(() => connect(attempt + 1), delay);
      };
    
      ws.onerror = (err) => {
        console.error("WebSocket error:", err);
        ws.close(); // triggers onclose → reconnect
      };
    }
    
    connect();

    Connection Example — Python (with auto-reconnect)

    import asyncio
    import websockets
    import json
    
    WS_URL = "wss://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/ws?api-key=smr_your_key"
    MAX_BACKOFF = 30
    
    async def on_signal(data):
        print(f"New: {data['symbol']} | Score: {data['radar_score']} | MC: ${data['market_cap']:,}")
    
    async def listen():
        attempt = 0
        while True:
            try:
                async with websockets.connect(WS_URL) as ws:
                    print("Connected to MemeScout Radar")
                    attempt = 0  # reset on success
                    async for raw in ws:
                        msg = json.loads(raw)
                        if msg["event"] == "snapshot":
                            print(f"Snapshot: {len(msg['data']['signals'])} active signals")
                            for s in msg["data"]["signals"]:
                                print(f"  {s['symbol']} | Score: {s['radar_score']}")
                        elif msg["event"] == "signal_new":
                            await on_signal(msg["data"])
                        elif msg["event"] == "signal_update":
                            await on_signal(msg["data"])  # same full payload
                        elif msg["event"] == "ping":
                            await ws.send(json.dumps({"event": "pong"}))
            except Exception as e:
                delay = min(2 ** attempt, MAX_BACKOFF)
                print(f"Disconnected ({e}). Reconnecting in {delay}s...")
                await asyncio.sleep(delay)
                attempt += 1
    
    asyncio.run(listen())

    Connection Limits & Behaviour

    • Max 2 concurrent connections per API key
    • Connections close after 5 minutes of inactivity (code 4008)
    • Connections close if heartbeat times out after 90s (code 4009)
    • Respond to ping events with pong to stay connected
    • Always implement reconnect logic — connections are not persistent
    • Requires Degen or Chad tier subscription

    Markdown for Agents
    AI-Ready

    Every MemeScout page is available as clean, token-efficient Markdown — ideal for AI agents, LLMs, and bots. Request any page as Markdown instead of scraping the HTML site (which returns JavaScript, not data).

    Do not scrape memescout.io/token/... directly

    MemeScout is a React SPA — the main site returns JavaScript bundles, not token data. Bots crawling https://memescout.io/token/<address> will only see JavaScript. Use the Markdown endpoint below instead.

    Endpoint

    GET https://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/markdown-for-agents?path=<path>

    No authentication required. Returns Content-Type: text/markdown with YAML front matter and an x-markdown-tokens header (estimated token count).

    Available Paths

    PathReturns
    ?path=/Site overview, navigation, radar description
    ?path=/pricingSubscription plans and FAQ
    ?path=/helpDashboard guide, radar score breakdown
    ?path=/docs/apiFull API reference
    ?path=/statsLive performance statistics (2x/5x/10x rates)
    ?path=/callsArchive overview — recent days and call counts
    ?path=/calls/YYYY-MM-DDAll tokens detected on a specific date with multipliers
    ?path=/token/:addressLive token data — price, MC, risk, radar score, multiplier

    Example — Token Detail

    # Fetch token data as Markdown (Python)
    import requests
    
    address = "BqqbcB2vdw2jnvANSxuBadnNsHdosuE9CtC599j7pump"
    url = f"https://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/markdown-for-agents?path=/token/{address}"
    
    response = requests.get(url, headers={"Accept": "text/markdown"})
    markdown = response.text
    
    # Response includes: price, market cap, liquidity, radar score,
    # risk level, top holder %, mint/freeze authority, multiplier
    print(markdown)

    Example — Specific Date Calls

    # Fetch all radar calls for a specific date
    curl "https://hctbncqmdygeymmtqjmj.supabase.co/functions/v1/markdown-for-agents?path=/calls/2026-03-24" \
      -H "Accept: text/markdown"
    
    # Returns: table of all tokens detected that day
    # Columns: Token, Symbol, Score, First MC, Peak MC, Multiplier, Trigger

    Discovery via robots.txt and llms.txt

    The markdown endpoint is advertised in /robots.txt and /llms.txt. Key pages also include a <link rel="alternate" type="text/markdown"> tag pointing directly to the markdown URL for that page.

    Ready to get started?

    Generate your API key and start building with Solana Meme Radar.