seoindiemonitoring

Building in Public: Track SEO Signals for Growth

From 0 to 128 signups by monitoring Reddit threads. Scale it: automated keyword tracking, Reddit monitoring, SERP position tracking at $0.50/day.

8 min

An indie hacker went from 0 to 128 signups by manually monitoring Reddit threads and responding to relevant questions. That approach works but does not scale past a few hours per day. Automated keyword tracking, Reddit mention monitoring, and SERP position tracking does the same thing programmatically at $0.50/day. Here is how to build the pipeline.

The manual approach that works (but does not scale)

The proven playbook: search Reddit for threads where people ask about your problem space, write helpful replies with a subtle mention of your product, and track which threads drive signups. At 128 signups from manual effort, the signal is clear: these channels work. The bottleneck is time, not strategy.

Automating keyword monitoring

Python
import requests, os, json
from datetime import date

HEADERS = {"x-api-key": os.environ["SCAVIO_API_KEY"]}

def monitor_brand_keywords(keywords: list, brand: str) -> dict:
    """Track where your brand appears (and does not) for target keywords."""
    results = {"mentioned": [], "opportunity": []}

    for keyword in keywords:
        resp = requests.post(
            "https://api.scavio.dev/api/v1/search",
            headers=HEADERS,
            json={"query": keyword, "platform": "google", "num_results": 20},
            timeout=10,
        )
        organic = resp.json().get("organic_results", [])

        brand_found = False
        for i, result in enumerate(organic, 1):
            if brand.lower() in result.get("link", "").lower():
                results["mentioned"].append({
                    "keyword": keyword,
                    "position": i,
                    "title": result["title"],
                    "date": str(date.today()),
                })
                brand_found = True
                break

        if not brand_found:
            results["opportunity"].append({
                "keyword": keyword,
                "top_result": organic[0]["title"] if organic else None,
                "top_domain": organic[0].get("link", "") if organic else None,
            })

    return results

# Track 20 keywords daily: 20 * $0.005 = $0.10/day
signals = monitor_brand_keywords(
    keywords=[
        "best search api for agents",
        "cheap serp api 2026",
        "tiktok data api alternative",
    ],
    brand="scavio",
)

Reddit mention monitoring

Python
def find_reddit_opportunities(topics: list) -> list:
    """Find Reddit threads where your product is relevant but not mentioned."""
    opportunities = []

    for topic in topics:
        resp = requests.post(
            "https://api.scavio.dev/api/v1/search",
            headers=HEADERS,
            json={
                "query": f"reddit {topic}",
                "platform": "google",
                "num_results": 10,
            },
            timeout=10,
        )
        results = resp.json().get("organic_results", [])

        for r in results:
            link = r.get("link", "")
            if "reddit.com" in link and "/comments/" in link:
                opportunities.append({
                    "topic": topic,
                    "title": r["title"],
                    "url": link,
                    "snippet": r.get("snippet", ""),
                    "found_date": str(date.today()),
                })

    return opportunities

# Find 30 Reddit threads across 10 topics: 10 * $0.005 = $0.05/day
threads = find_reddit_opportunities([
    "search api recommendation",
    "serp scraping alternative",
    "tiktok analytics api",
    "seo tool for developers",
    "agent search grounding",
])

SERP position tracking over time

Python
import sqlite3

def init_tracking_db():
    conn = sqlite3.connect("seo_signals.db")
    conn.execute("""
        CREATE TABLE IF NOT EXISTS serp_positions (
            id INTEGER PRIMARY KEY,
            date TEXT,
            keyword TEXT,
            position INTEGER,
            title TEXT,
            url TEXT,
            UNIQUE(date, keyword)
        )
    """)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS reddit_opportunities (
            id INTEGER PRIMARY KEY,
            found_date TEXT,
            topic TEXT,
            title TEXT,
            url TEXT UNIQUE,
            responded BOOLEAN DEFAULT 0,
            signups_attributed INTEGER DEFAULT 0
        )
    """)
    return conn

def daily_tracking_run(conn, keywords: list, brand: str, topics: list):
    """Full daily tracking pipeline."""
    # Track SERP positions
    brand_signals = monitor_brand_keywords(keywords, brand)
    for entry in brand_signals["mentioned"]:
        try:
            conn.execute(
                "INSERT INTO serp_positions VALUES (NULL, ?, ?, ?, ?, ?)",
                (entry["date"], entry["keyword"], entry["position"],
                 entry["title"], ""),
            )
        except sqlite3.IntegrityError:
            pass

    # Find Reddit opportunities
    threads = find_reddit_opportunities(topics)
    for thread in threads:
        try:
            conn.execute(
                "INSERT INTO reddit_opportunities VALUES (NULL, ?, ?, ?, ?, 0, 0)",
                (thread["found_date"], thread["topic"],
                 thread["title"], thread["url"]),
            )
        except sqlite3.IntegrityError:
            pass

    conn.commit()
    return {
        "positions_tracked": len(brand_signals["mentioned"]),
        "new_opportunities": len(threads),
        "gaps_found": len(brand_signals["opportunity"]),
    }

Daily cost breakdown

  • Brand keyword monitoring (20 keywords): $0.10/day
  • Reddit opportunity scanning (10 topics): $0.05/day
  • Competitor position checks (20 keywords): $0.10/day
  • AI Overview citation checks (10 keywords): $0.05/day
  • Total: $0.30-0.50/day ($9-15/month)

Prioritizing responses for maximum signups

Python
def prioritize_opportunities(conn) -> list:
    """Rank Reddit threads by likely conversion potential."""
    threads = conn.execute("""
        SELECT * FROM reddit_opportunities
        WHERE responded = 0
        ORDER BY found_date DESC
    """).fetchall()

    scored = []
    for thread in threads:
        score = 0
        title = thread[3].lower()

        # High intent signals
        if any(w in title for w in ["recommend", "best", "looking for", "alternative"]):
            score += 3
        if any(w in title for w in ["api", "developer", "build", "automate"]):
            score += 2
        if "2026" in title or "new" in title:
            score += 1

        scored.append({"thread": thread, "score": score})

    return sorted(scored, key=lambda x: x["score"], reverse=True)

Measuring what works

Track signups back to their source: UTM parameters on links in Reddit responses, position changes correlated with content published, and AI Overview appearances. After 30 days of automated tracking, you will know which keywords drive traffic, which Reddit topics convert, and where your SERP positions are trending. This data tells you where to double down -- and where to stop spending time.

The indie hacker who got 128 signups manually proved the channel works. Automation at $0.50/day scales it without scaling your time investment. Monitor, prioritize, respond to the highest-value threads, and track attribution. Repeat daily.