Skip to main content
← Back to blog
by Engineering

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 is that 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 at the cadence below costs roughly:

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. Even so, this cadence adds up to roughly 70K credits/day (about 2.1M/month), so always-on monitoring at full speed fits the Pro plan (2M credits/mo) topped up with a pay-as-you-go pack, or a PAYG budget. To run it on the Basic plan ($4.9/mo, 700K credits) instead, widen the poll intervals to every 15-20 minutes, which brings the daily cost comfortably under the monthly cap.

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: an 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 whether they're worth acting on.

Build this with the XCROP API

One API for X/Twitter data: profiles, tweets, followers, search and real-time streams. Start free with 5,000 credits/month, no card required.