seorank-trackingtools

Why I Built My Own Rank Tracker (And What I Discovered)

Building a custom rank tracker using a SERP API and discovering what commercial tools hide about real search data.

9 min read

Commercial rank trackers cost $50-500 per month and give you a dashboard you did not ask for. They track keywords on a schedule they choose, from locations they support, with data freshness they control. If you want something different -- custom metrics, raw SERP data, integration with your own tools -- you are out of luck.

Building your own rank tracker with a SERP API takes a few hours and costs a fraction of what commercial tools charge. More importantly, you get access to the raw search data, not just a position number.

Why Build Your Own

The main reasons to build a custom rank tracker:

  • You want raw SERP features (People Also Ask, knowledge graph, featured snippets) not just rank position
  • You need to track competitors' SERP features, not just their rank
  • You want to integrate ranking data into your existing analytics pipeline
  • You need custom alerting logic beyond simple position changes
  • You want to control the check frequency and locations

The Basic Tracker

At its core, a rank tracker searches Google for a keyword and finds your domain in the results:

interface RankResult {
  keyword: string;
  position: number | null;
  url: string | null;
  title: string | null;
  featuredSnippet: boolean;
  peopleAlsoAsk: string[];
  checkedAt: string;
}

async function checkRank(
  keyword: string,
  domain: string
): Promise<RankResult> {
  const res = await fetch("https://api.scavio.dev/api/v1/search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": process.env.SCAVIO_API_KEY
    },
    body: JSON.stringify({
      platform: "google",
      query: keyword,
      mode: "full",
      gl: "us"
    })
  });
  const data = await res.json();
  const organic = data.organic ?? [];
  const idx = organic.findIndex(
    (r: any) => r.link?.includes(domain)
  );

  return {
    keyword,
    position: idx === -1 ? null : idx + 1,
    url: idx === -1 ? null : organic[idx].link,
    title: idx === -1 ? null : organic[idx].title,
    featuredSnippet: data.featuredSnippet?.link?.includes(domain) ?? false,
    peopleAlsoAsk: data.peopleAlsoAsk?.map((q: any) => q.question) ?? [],
    checkedAt: new Date().toISOString()
  };
}

Tracking SERP Features

This is where a custom tracker shines. Commercial tools tell you your position is 4. Your tracker tells you that position 1 is a featured snippet from your competitor, positions 2-3 are Reddit threads, and position 4 is you -- but there is also a People Also Ask box pushing you below the fold.

Scavio's full mode returns all of this data:

  • Featured snippets with source URL and content
  • People Also Ask questions and their answers
  • Knowledge graph panels
  • Local pack results
  • Image and video carousels
  • News results and their timestamps

Batch Checking and Storage

Run your full keyword list on a schedule and store the results:

async function dailyRankCheck(
  keywords: string[],
  domain: string
) {
  const results: RankResult[] = [];
  for (const keyword of keywords) {
    const result = await checkRank(keyword, domain);
    results.push(result);
    // Respect rate limits
    await new Promise((r) => setTimeout(r, 1000));
  }
  // Store in your database
  await db.insert("rank_checks", results);
  // Check for significant changes
  const alerts = await detectChanges(results);
  if (alerts.length > 0) {
    await sendAlerts(alerts);
  }
}

What You Discover

When you have access to raw SERP data, you notice things commercial trackers hide:

  • Position 1 is meaningless if a featured snippet owns the click
  • Your position can stay the same while the SERP layout changes dramatically
  • People Also Ask boxes reveal content opportunities your competitors miss
  • Local pack results cannibalize organic clicks for certain queries

A position number without context is just a vanity metric. The SERP layout tells you whether that position actually drives traffic.

Cost Math

Tracking 100 keywords daily with Scavio costs roughly $3 per month at standard pricing. A commercial rank tracker charges $50-100 per month for the same keyword volume but gives you less data. At 500 keywords, the savings are even more significant. And you own the data -- no vendor lock-in, no export limitations, no surprise price increases.