Tutorial

How to Build an Agency Rank Tracker with a Search API

Build a rank tracker for SEO agency clients using a search API. Track Google positions daily without dedicated rank tracking tools.

SEO agencies pay $100-500/month for rank tracking tools (Ahrefs, SEMrush, AccuRanker). For agencies tracking moderate keyword volumes, a search API at $0.005/query can replicate core rank tracking at a fraction of the cost. This tutorial builds a daily rank tracker for agency clients.

Prerequisites

  • Python 3.8+
  • A Scavio API key
  • Client keywords and target URLs

Walkthrough

Step 1: Define client keyword sets

Structure client data with keywords and target domains.

Python
CLIENTS = [
    {
        'name': 'Client A',
        'domain': 'clienta.com',
        'keywords': ['crm software', 'best crm 2026', 'crm for startups', 'crm comparison'],
    },
    {
        'name': 'Client B',
        'domain': 'clientb.io',
        'keywords': ['project management tool', 'team collaboration app', 'agile project management'],
    },
]

Step 2: Build the rank checker

Search Google for each keyword and find the client's position.

Python
import requests, os

H = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def check_rank(keyword: str, target_domain: str) -> dict:
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': keyword}, timeout=10)
    results = resp.json().get('organic', [])
    
    for i, r in enumerate(results):
        url = r.get('link', '')
        if target_domain in url:
            return {'keyword': keyword, 'position': i + 1, 'url': url, 'title': r.get('title','')}
    
    return {'keyword': keyword, 'position': None, 'not_in_top_results': True}

Step 3: Run daily tracking

Check all keywords for a client and store historical data.

Python
import json
from datetime import date
from pathlib import Path

def daily_client_check(client: dict) -> dict:
    today = date.today().isoformat()
    results = []
    for kw in client['keywords']:
        rank = check_rank(kw, client['domain'])
        rank['date'] = today
        results.append(rank)
    
    # Store history
    history_file = Path(f"ranks_{client['name'].replace(' ','_').lower()}.json")
    history = json.loads(history_file.read_text()) if history_file.exists() else []
    history.extend(results)
    history_file.write_text(json.dumps(history, indent=2))
    
    return {
        'client': client['name'],
        'date': today,
        'tracked': len(results),
        'ranking': sum(1 for r in results if r.get('position')),
        'avg_position': sum(r['position'] for r in results if r.get('position')) / max(sum(1 for r in results if r.get('position')), 1),
        'results': results,
    }

Step 4: Generate client report

Create a summary report showing position changes over time.

Python
def client_report(client_name: str, days: int = 7) -> dict:
    history_file = Path(f"ranks_{client_name.replace(' ','_').lower()}.json")
    if not history_file.exists():
        return {'error': 'No data found'}
    
    history = json.loads(history_file.read_text())
    dates = sorted(set(r['date'] for r in history))[-days:]
    
    report = {'client': client_name, 'period': f'Last {days} days', 'keywords': {}}
    for kw in set(r['keyword'] for r in history):
        kw_data = [r for r in history if r['keyword'] == kw and r['date'] in dates]
        if len(kw_data) >= 2:
            first = next((r['position'] for r in kw_data if r.get('position')), None)
            last = next((r['position'] for r in reversed(kw_data) if r.get('position')), None)
            if first and last:
                report['keywords'][kw] = {'current': last, 'change': first - last, 'trend': 'up' if last < first else 'down' if last > first else 'stable'}
    
    return report

Python Example

Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def check_rank(keyword, domain):
    r = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': keyword}).json()
    for i, x in enumerate(r.get('organic',[])):
        if domain in x.get('link',''):
            return i + 1
    return None

JavaScript Example

JavaScript
async function checkRank(keyword, domain) {
  const r = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
    body: JSON.stringify({platform: 'google', query: keyword})
  });
  const results = (await r.json()).organic || [];
  const idx = results.findIndex(x => x.link?.includes(domain));
  return idx >= 0 ? idx + 1 : null;
}

Expected Output

JSON
A daily rank tracker that monitors Google positions for agency clients, stores historical data, and generates position change reports.

Related Tutorials

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.8+. A Scavio API key. Client keywords and target URLs. A Scavio API key gives you 500 free credits per month.

Yes. The free tier includes 500 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.

Start Building

Build a rank tracker for SEO agency clients using a search API. Track Google positions daily without dedicated rank tracking tools.