Skip to main content
← Back to blog
by Engineering
cryptoalphatutorial

Monitor New Token Launches on Twitter: Early Alpha Detection

The Alpha Advantage

In crypto, being early is everything. A token that does 50x in 24 hours often has its first signal on Twitter — a developer posting a contract address, a KOL mentioning a "stealth launch," or a sudden spike in mentions for an unknown ticker.

The problem? Manually scrolling through Twitter is slow and unreliable. By the time you see a launch tweet in your feed, hundreds of bots and snipers have already aped in.

This guide shows you how to build an automated token launch detector using XCROP's Search API — so you catch launches in minutes, not hours.

The Detection Strategy

Our detector combines three signals:

1. Contract address mentions — New tokens get posted with their CA (contract address) on Twitter
2. Launch keywords — Phrases like "just launched," "stealth launch," "fair launch" signal new deployments
3. Engagement velocity — Sudden spikes in likes/retweets on a low-follower account often indicate coordinated shilling

Search Queries by Chain

Different chains have different patterns. Here are optimized search queries for each:

Ethereum / ERC-20

PYTHON
queries_eth = [
    "0x AND (just launched OR stealth launch OR fair launch) -filter:retweets",
    "contract address 0x AND (dex OR uniswap OR liquidity) -filter:retweets",
    "new token 0x AND (etherscan OR dextools) -filter:retweets",
]

Solana / SPL

PYTHON
queries_sol = [
    "(pump.fun OR raydium) AND (just launched OR new token OR stealth) -filter:retweets",
    "solana AND CA AND (launch OR deployed OR live) -filter:retweets",
    "SOL AND contract AND (dexscreener OR birdeye OR jupiter) -filter:retweets",
]

Base

PYTHON
queries_base = [
    "base chain AND (just launched OR new token OR stealth launch) -filter:retweets",
    "0x AND (base OR basescan) AND (launch OR deployed) -filter:retweets",
    "base AND (aerodrome OR uniswap) AND new token -filter:retweets",
]

Building the Token Launch Detector

Here's a complete Python script that monitors Twitter for new token launches:

PYTHON
import requests
import time
import re
import json
from datetime import datetime, timedelta

XCROP_API_KEY = "xc_live_your_api_key_here"
BASE_URL = "https://xcrop.io/api/v2"
HEADERS = {
    "Authorization": f"Bearer {XCROP_API_KEY}",
    "Content-Type": "application/json"
}

# Patterns to detect contract addresses
CA_PATTERNS = {
    "ETH": r"0x[a-fA-F0-9]{40}",
    "SOL": r"[1-9A-HJ-NP-Za-km-z]{32,44}",
}

# Search queries for new launches
SEARCH_QUERIES = [
    "just launched AND (contract OR CA OR 0x) -filter:retweets",
    "stealth launch AND (token OR coin OR dex) -filter:retweets",
    "fair launch AND (uniswap OR raydium OR pump.fun) -filter:retweets",
    "new token AND (liquidity added OR LP locked) -filter:retweets",
    "deploy AND (contract address OR CA) AND (sol OR eth OR base) -filter:retweets",
]


def search_tweets(query, count=20):
    """Search Twitter via XCROP API."""
    response = requests.post(
        f"{BASE_URL}/search",
        headers=HEADERS,
        json={"query": query, "count": count}
    )
    if response.status_code != 200:
        print(f"Search error: {response.status_code}")
        return []
    return response.json().get("data", [])


def extract_addresses(text):
    """Extract potential contract addresses from tweet text."""
    found = {}
    for chain, pattern in CA_PATTERNS.items():
        matches = re.findall(pattern, text)
        if matches:
            found[chain] = matches
    return found


def calculate_engagement_score(tweet):
    """Score a tweet based on engagement velocity."""
    likes = tweet.get("likes", 0)
    retweets = tweet.get("retweets", 0)
    replies = tweet.get("replies", 0)
    views = tweet.get("views", 1)

    # High engagement relative to views = organic interest
    engagement_rate = (likes + retweets * 2 + replies * 3) / max(views, 1)

    # Bonus for quote tweets (people discussing it)
    quote_bonus = tweet.get("quotes", 0) * 5

    return round((engagement_rate * 10000) + quote_bonus, 2)


def check_trending_boost():
    """Check if any crypto topics are trending."""
    response = requests.get(
        f"{BASE_URL}/trending",
        headers={"Authorization": f"Bearer {XCROP_API_KEY}"}
    )
    if response.status_code != 200:
        return []

    topics = response.json().get("data", [])
    crypto_keywords = ["token", "coin", "launch", "airdrop", "dex", "nft",
                       "defi", "sol", "eth", "base", "pump"]

    return [
        t for t in topics
        if any(kw in t.get("name", "").lower() for kw in crypto_keywords)
    ]


def analyze_author(username):
    """Quick check on tweet author — new accounts shilling = red flag."""
    response = requests.get(
        f"{BASE_URL}/users/{username}",
        headers={"Authorization": f"Bearer {XCROP_API_KEY}"}
    )
    if response.status_code != 200:
        return None

    user = response.json().get("data", {})
    return {
        "username": username,
        "followers": user.get("followers", 0),
        "following": user.get("following", 0),
        "tweets": user.get("tweets_count", 0),
        "created": user.get("created_at", ""),
        "verified": user.get("verified", False),
    }


def run_scan():
    """Run a single scan cycle."""
    print(f"\n{'='*60}")
    print(f"Scan at {datetime.now().strftime('%H:%M:%S')}")
    print(f"{'='*60}")

    all_signals = []

    # 1. Search for launch tweets
    for query in SEARCH_QUERIES:
        tweets = search_tweets(query, count=20)
        for tweet in tweets:
            addresses = extract_addresses(tweet.get("text", ""))
            if not addresses:
                continue

            score = calculate_engagement_score(tweet)
            signal = {
                "tweet_id": tweet.get("id"),
                "text": tweet.get("text", "")[:200],
                "author": tweet.get("author", {}).get("username", "unknown"),
                "addresses": addresses,
                "engagement_score": score,
                "likes": tweet.get("likes", 0),
                "retweets": tweet.get("retweets", 0),
                "created_at": tweet.get("created_at", ""),
            }
            all_signals.append(signal)

        time.sleep(1)  # Respect rate limits

    # 2. Check trending for crypto surge
    trending_crypto = check_trending_boost()
    if trending_crypto:
        print(f"\nCrypto trending: {[t['name'] for t in trending_crypto[:5]]}")

    # 3. Deduplicate by contract address
    seen_addresses = set()
    unique_signals = []
    for signal in all_signals:
        for chain, addrs in signal["addresses"].items():
            for addr in addrs:
                if addr not in seen_addresses:
                    seen_addresses.add(addr)
                    unique_signals.append(signal)

    # 4. Sort by engagement score
    unique_signals.sort(key=lambda s: s["engagement_score"], reverse=True)

    # 5. Display results
    if not unique_signals:
        print("No new token signals detected.")
        return

    print(f"\nFound {len(unique_signals)} potential launches:\n")
    for i, signal in enumerate(unique_signals[:10], 1):
        print(f"{i}. @{signal['author']} (score: {signal['engagement_score']})")
        print(f"   {signal['text'][:120]}...")
        for chain, addrs in signal["addresses"].items():
            print(f"   {chain}: {addrs[0]}")
        print(f"   Engagement: {signal['likes']} likes, "
              f"{signal['retweets']} RTs")
        print()

    return unique_signals


# ── Main Loop ──────────────────────────────────────────────────

if __name__ == "__main__":
    print("Token Launch Detector — powered by XCROP API")
    print("Scanning every 2 minutes...\n")

    while True:
        try:
            signals = run_scan()

            # Optional: send alerts (Telegram, Discord, etc.)
            # if signals:
            #     send_telegram_alert(signals[0])

        except KeyboardInterrupt:
            print("\nStopped.")
            break
        except Exception as e:
            print(f"Error: {e}")

        time.sleep(120)  # Scan every 2 minutes

Filtering False Positives

Raw search results will include noise. Here are filters that dramatically improve signal quality:

Engagement Threshold

PYTHON
# Only surface tweets with meaningful engagement
MIN_LIKES = 5
MIN_RETWEETS = 2

filtered = [
    s for s in signals
    if s["likes"] >= MIN_LIKES or s["retweets"] >= MIN_RETWEETS
]

Account Age Filter

PYTHON
# Skip brand-new accounts (common for scam launches)
def is_suspicious_account(author_info):
    if not author_info:
        return True

    # Account less than 30 days old
    created = datetime.strptime(author_info["created"], "%Y-%m-%dT%H:%M:%S.000Z")
    age_days = (datetime.now() - created).days
    if age_days < 30:
        return True

    # Very low followers but high tweet count = bot pattern
    if author_info["followers"] < 50 and author_info["tweets"] > 5000:
        return True

    return False

Duplicate Contract Detection

PYTHON
# Track seen contracts across scans to avoid re-alerting
seen_contracts = {}  # address -> first_seen_timestamp

def is_new_contract(address):
    if address in seen_contracts:
        return False
    seen_contracts[address] = datetime.now()
    return True

Advanced: Combining with User Tweets

The highest-alpha signal is when a known KOL mentions a new token. Use the User Tweets endpoint (/v2/users/{kol}/tweets) to monitor influencer activity — call it once per KOL and merge the results:

PYTHON
KOL_WATCHLIST = ["CryptoHayes", "DefiIgnas", "Pentosh1", "blaboratory"]

def check_kol_mentions():
    """Monitor KOL timelines for token mentions."""
    tweets = []
    for kol in KOL_WATCHLIST:
        response = requests.get(
            f"{BASE_URL}/users/{kol}/tweets?count=20",
            headers={"Authorization": f"Bearer {XCROP_API_KEY}"}
        )
        if response.status_code == 200:
            tweets += response.json().get("data", [])
    kol_signals = []

    for tweet in tweets:
        addresses = extract_addresses(tweet.get("text", ""))
        if addresses:
            kol_signals.append({
                "kol": tweet.get("author", {}).get("username"),
                "followers": tweet.get("author", {}).get("followers", 0),
                "addresses": addresses,
                "text": tweet.get("text", "")[:200],
                "tweet_id": tweet.get("id"),
            })

    return kol_signals

When a KOL with 100K+ followers posts a contract address, that's a high-confidence signal worth immediate attention.

The Complete Alpha Workflow

Here's how to put it all together for maximum alpha:

1. Every 2 minutes: Run search queries for launch keywords + contract addresses
2. Every 5 minutes: Check KOL user tweets for influencer mentions
3. Every 10 minutes: Check trending topics for crypto surges
4. On detection: Verify contract on-chain (Etherscan/Solscan API), check liquidity, then alert
5. Alert channels: Telegram bot, Discord webhook, or desktop notification

Credit Budget

Running this detector 24/7 on XCROP's Basic plan ($4.9/mo, 700K credits):

CheckFrequencyCredits/callDaily cost
Search (5 queries)Every 2 min~45~32,400
User tweets (4 KOLs)Every 5 min~90~25,920
TrendingEvery 10 min100~14,400

Search and user-tweet calls bill at 15 credits per result returned, so incremental polls that surface only a handful of new tweets stay cheap. That's roughly 70K credits/day — well within the Basic plan ($4.9/mo, 700K credits) with plenty of headroom for continuous monitoring.

Safety Reminders

Detecting token launches early is powerful, but always DYOR:

Verify liquidity — Check if LP is locked (rug pull risk if not)
Check contract — Look for honeypot patterns, mint functions, high tax
Watch the dev wallet — If the deployer holds 80%+ supply, be cautious
Don't ape blindly — Early signal does not mean guaranteed profit
Size your risk — Never invest more than you can afford to lose on a new launch

The detector finds signals — your research determines if they're worth acting on.