ScavioScavio
FeaturesPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Build Your Own Rank Tracker API Without Scraping
Tutorial

How to Build Your Own Rank Tracker API Without Scraping

Build a complete keyword rank tracking API in Python using the Scavio search API. Track daily positions for unlimited keywords without managing any scrapers.

Get Free API KeyAPI Docs

Most rank trackers are built on top of fragile scrapers that break every time Google changes its HTML. By using the Scavio API as the data layer, you can build a rank tracker that returns structured position data without maintaining proxies or parsers. This tutorial builds a lightweight Flask API that accepts keyword and domain inputs, checks Google positions via Scavio, stores results in SQLite, and exposes historical ranking data through a REST endpoint.

Prerequisites

  • Python 3.10 or higher
  • pip install requests flask
  • A Scavio API key
  • Basic understanding of REST API design

Walkthrough

Step 1: Set up the SQLite database

Create a simple table to store keyword, domain, position, and timestamp for each check.

Python
import sqlite3

def init_db(path: str = "rankings.db") -> None:
    conn = sqlite3.connect(path)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS rankings (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            keyword TEXT NOT NULL,
            domain TEXT NOT NULL,
            position INTEGER,
            checked_at TEXT DEFAULT (datetime('now'))
        )
    """)
    conn.commit()
    conn.close()

Step 2: Check rank via Scavio

Query Google through the Scavio API and scan results for the target domain. Return the position or None.

Python
import requests

def check_rank(keyword: str, domain: str) -> int | None:
    r = requests.post(
        "https://api.scavio.dev/api/v1/search",
        headers={"x-api-key": API_KEY},
        json={"query": keyword, "country_code": "us"}
    )
    r.raise_for_status()
    for result in r.json().get("organic_results", []):
        if domain in result.get("link", ""):
            return result["position"]
    return None

Step 3: Store and retrieve rankings

Save each rank check to SQLite and provide a function to query historical data.

Python
def save_rank(keyword: str, domain: str, position: int | None) -> None:
    conn = sqlite3.connect("rankings.db")
    conn.execute("INSERT INTO rankings (keyword, domain, position) VALUES (?, ?, ?)",
                 (keyword, domain, position))
    conn.commit()
    conn.close()

def get_history(keyword: str, domain: str, days: int = 30) -> list[dict]:
    conn = sqlite3.connect("rankings.db")
    rows = conn.execute(
        "SELECT position, checked_at FROM rankings WHERE keyword=? AND domain=? ORDER BY checked_at DESC LIMIT ?",
        (keyword, domain, days)
    ).fetchall()
    conn.close()
    return [{"position": r[0], "date": r[1]} for r in rows]

Step 4: Expose as a Flask API

Create two endpoints: POST /check to trigger a rank check, and GET /history to retrieve stored positions.

Python
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/check", methods=["POST"])
def check():
    data = request.json
    pos = check_rank(data["keyword"], data["domain"])
    save_rank(data["keyword"], data["domain"], pos)
    return jsonify({"keyword": data["keyword"], "domain": data["domain"], "position": pos})

@app.route("/history")
def history():
    kw = request.args["keyword"]
    domain = request.args["domain"]
    return jsonify(get_history(kw, domain))

Python Example

Python
import os
import sqlite3
import requests
from flask import Flask, request, jsonify

API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"
DB = "rankings.db"

def init_db():
    conn = sqlite3.connect(DB)
    conn.execute("CREATE TABLE IF NOT EXISTS rankings (id INTEGER PRIMARY KEY AUTOINCREMENT, keyword TEXT, domain TEXT, position INTEGER, checked_at TEXT DEFAULT (datetime('now')))")
    conn.commit()
    conn.close()

def check_rank(keyword: str, domain: str) -> int | None:
    r = requests.post(ENDPOINT, headers={"x-api-key": API_KEY},
                      json={"query": keyword, "country_code": "us"})
    r.raise_for_status()
    for res in r.json().get("organic_results", []):
        if domain in res.get("link", ""):
            return res["position"]
    return None

app = Flask(__name__)

@app.route("/check", methods=["POST"])
def check():
    d = request.json
    pos = check_rank(d["keyword"], d["domain"])
    conn = sqlite3.connect(DB)
    conn.execute("INSERT INTO rankings (keyword, domain, position) VALUES (?, ?, ?)", (d["keyword"], d["domain"], pos))
    conn.commit()
    conn.close()
    return jsonify({"keyword": d["keyword"], "position": pos})

if __name__ == "__main__":
    init_db()
    app.run(port=5000)

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/search";

async function checkRank(keyword, domain) {
  const res = await fetch(ENDPOINT, {
    method: "POST",
    headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ query: keyword, country_code: "us" })
  });
  const data = await res.json();
  const match = (data.organic_results || []).find(r => r.link.includes(domain));
  return match ? match.position : null;
}

async function main() {
  const keywords = ["python api tutorial", "rest api guide"];
  const domain = "mysite.com";
  for (const kw of keywords) {
    const pos = await checkRank(kw, domain);
    console.log(`${kw}: ${pos ? "#" + pos : "not ranked"}`);
  }
}
main().catch(console.error);

Expected Output

JSON
POST /check {"keyword": "python api tutorial", "domain": "mysite.com"}
=> {"keyword": "python api tutorial", "position": 6}

GET /history?keyword=python+api+tutorial&domain=mysite.com
=> [{"position": 6, "date": "2026-04-19"}, {"position": 7, "date": "2026-04-18"}]

Related Tutorials

  • How to Track SEO Rankings Daily with the Scavio API
  • How to Build an SEO Audit Dashboard with API Data

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.10 or higher. pip install requests flask. A Scavio API key. Basic understanding of REST API design. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Related Resources

Best Of

Best API-Based Rank Trackers for SEO in 2026

Read more
Best Of

Best SEO Rank Tracking APIs in 2026

Read more
Solution

Build Reliable Local Rank Tracking with Scavio API

Read more
Solution

Run SEO Rank Checks Overnight in Batch Mode

Read more
Use Case

SEO Light User API Workflow

Read more
Use Case

AppSumo SEO Tool to API Migration

Read more

Start Building

Build a complete keyword rank tracking API in Python using the Scavio search API. Track daily positions for unlimited keywords without managing any scrapers.

Get Free API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy