Perplexity returns citations with each answer, which makes it the easiest AI engine to benchmark. This tutorial builds a per-source citation tracker that ranks your domain against competitors across a query panel, with week-over-week change.
Prerequisites
- Python 3.10+
- A Scavio API key
- SQLite
- A competitive query panel
Walkthrough
Step 1: Define the query panel
30-100 queries your buyers ask Perplexity.
QUERIES = [
'best serp api',
'cheapest google search api',
'tavily alternative 2026'
]Step 2: Run queries through Scavio Perplexity
Platform: perplexity returns an answer plus structured sources.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
def ask_perplexity(query):
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': 'perplexity', 'query': query})
return r.json()Step 3: Aggregate by domain
Count citation hits per domain across all queries.
from urllib.parse import urlparse
from collections import Counter
def domain_counts(all_responses):
c = Counter()
for resp in all_responses:
for src in resp.get('sources', []):
c[urlparse(src['url']).netloc] += 1
return cStep 4: Compare to last week
Store snapshots and compute delta.
import sqlite3, json
conn = sqlite3.connect('pplx.db')
conn.execute('CREATE TABLE IF NOT EXISTS snaps (date TEXT, counts TEXT)')
def snapshot(counts):
conn.execute('INSERT INTO snaps VALUES (date(\'now\'), ?)', (json.dumps(counts),))
conn.commit()Step 5: Alert on competitor gains
Slack ping when a competitor's count jumps 25%+ week over week.
def alert(prev, now, threshold=0.25):
for d, n in now.items():
p = prev.get(d, 1)
if (n - p) / p > threshold:
print(f'Competitor {d} grew {(n-p)/p:.0%}')Python Example
import os, requests
from urllib.parse import urlparse
from collections import Counter
API_KEY = os.environ['SCAVIO_API_KEY']
QUERIES = ['best serp api', 'cheapest google search api']
counts = Counter()
for q in QUERIES:
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': 'perplexity', 'query': q})
for s in r.json().get('sources', []):
counts[urlparse(s['url']).netloc] += 1
print(counts.most_common(10))JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY;
const QUERIES = ['best serp api', 'cheapest google search api'];
const counts = {};
for (const q of QUERIES) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ platform: 'perplexity', query: q })
});
const data = await r.json();
for (const s of data.sources || []) {
const d = new URL(s.url).hostname;
counts[d] = (counts[d] || 0) + 1;
}
}
console.log(Object.entries(counts).sort((a,b) => b[1]-a[1]).slice(0,10));Expected Output
Per-domain citation counter ranked top 10. Week-over-week delta highlights competitor gains. Typical signal: competitor jumps from 3 to 12 citations week-over-week triggers content response.