Scenario
Compare domain ratings and backlink profiles across your competitors to understand authority gaps, then use Mavera to craft competitive positioning messaging and an authority-appropriate brand voice. Themetrics endpoint returns domain rating, total backlinks, referring domains, and organic traffic estimates for any target.
Architecture
Code
import os, requests, time
AH = os.environ["AHREFS_API_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
MB = "https://app.mavera.io/api/v1"
AH_H = {"Authorization": f"Bearer {AH}", "Accept": "application/json"}
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
DOMAINS = ["yourdomain.com", "competitor1.com", "competitor2.com", "competitor3.com"]
metrics = []
for domain in DOMAINS:
resp = requests.get("https://api.ahrefs.com/v3/site-explorer/metrics", headers=AH_H,
params={"target": domain, "select": "domain_rating,backlinks,referring_domains,"
"organic_traffic,organic_keywords"})
resp.raise_for_status()
data = resp.json()
data["domain"] = domain
metrics.append(data)
time.sleep(1)
metrics.sort(key=lambda m: m.get("domain_rating", 0), reverse=True)
landscape = "\n".join(
f"- {m['domain']} | DR: {m.get('domain_rating', 0)} | backlinks: {m.get('backlinks', 0):,} | "
f"ref domains: {m.get('referring_domains', 0):,} | traffic: {m.get('organic_traffic', 0):,}"
for m in metrics)
our = next(m for m in metrics if m["domain"] == DOMAINS[0])
our_rank = next(i for i, m in enumerate(metrics) if m["domain"] == DOMAINS[0]) + 1
print(f"Your DR: {our.get('domain_rating', 0)} (#{our_rank}/{len(DOMAINS)})\n{landscape}")
positioning = requests.post(f"{MB}/mave/chat", headers=MH, json={
"message": f"Competitive SEO positioning.\n\nLANDSCAPE:\n{landscape}\n\n"
f"We are: {DOMAINS[0]} (#{our_rank}).\n\nProvide: 1) Authority gap "
f"2) Backlink strategy 3) Differentiation 4) Messaging positioning "
f"5) 3 positioning statements",
}).json()
print("\n=== Positioning ===")
print(positioning.get("content", "")[:1500])
bv = requests.post(f"{MB}/brand-voices", headers=MH, json={
"name": f"Authority Voice — DR {our.get('domain_rating', 0)}",
"description": f"Voice for DR {our.get('domain_rating', 0)}, #{our_rank} of "
f"{len(DOMAINS)}. Confident, data-led, not defensive.",
"samples": [
"We test content with real audiences before publishing — that's why it converts.",
"3,000+ focus group responses shaped this. Others guess. We validate.",
],
}).json()
print(f"\nBrand voice: {bv.get('id')}")
const AH = process.env.AHREFS_API_TOKEN, MV = process.env.MAVERA_API_KEY;
const MB = "https://app.mavera.io/api/v1";
const AH_H = { Authorization: `Bearer ${AH}`, Accept: "application/json" };
const MH = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
const DOMAINS = ["yourdomain.com", "competitor1.com", "competitor2.com", "competitor3.com"];
const metrics = [];
for (const domain of DOMAINS) {
const params = new URLSearchParams({ target: domain,
select: "domain_rating,backlinks,referring_domains,organic_traffic,organic_keywords" });
const data = await fetch(
`https://api.ahrefs.com/v3/site-explorer/metrics?${params}`, { headers: AH_H }
).then((r) => r.json());
data.domain = domain;
metrics.push(data);
await new Promise((r) => setTimeout(r, 1000));
}
metrics.sort((a, b) => (b.domain_rating || 0) - (a.domain_rating || 0));
const landscape = metrics.map((m) =>
`- ${m.domain} | DR: ${m.domain_rating || 0} | backlinks: ${(m.backlinks || 0).toLocaleString()}`
).join("\n");
const ourRank = metrics.findIndex((m) => m.domain === DOMAINS[0]) + 1;
const our = metrics.find((m) => m.domain === DOMAINS[0]);
console.log(`Your DR: ${our.domain_rating || 0} (#${ourRank}/${DOMAINS.length})\n`);
const pos = await fetch(`${MB}/mave/chat`, { method: "POST", headers: MH,
body: JSON.stringify({
message: `Competitive positioning.\nLANDSCAPE:\n${landscape}\nWe: ${DOMAINS[0]} (#${ourRank}).\n`
+ `1) Authority gaps 2) Backlink strategy 3) Differentiation 4) Positioning 5) 3 statements`,
}),
}).then((r) => r.json());
console.log("=== Positioning ===\n" + (pos.content || "").slice(0, 1500));
const bv = await fetch(`${MB}/brand-voices`, { method: "POST", headers: MH,
body: JSON.stringify({
name: `Authority Voice — DR ${our.domain_rating || 0}`,
description: `DR ${our.domain_rating || 0}, #${ourRank}. Confident, data-led.`,
samples: ["We test with real audiences — that's why it converts.",
"3,000+ focus group responses shaped this. Others guess. We validate."],
}),
}).then((r) => r.json());
console.log(`\nBrand voice: ${bv.id}`);
Example Output
{
"landscape": [
{ "domain": "competitor1.com", "domain_rating": 78, "backlinks": 245000 },
{ "domain": "competitor2.com", "domain_rating": 65, "backlinks": 89000 },
{ "domain": "yourdomain.com", "domain_rating": 52, "backlinks": 34000 },
{ "domain": "competitor3.com", "domain_rating": 41, "backlinks": 12000 }
],
"authority_gap": "26 DR points behind leader — closable with focused link building",
"brand_voice_id": "bv_a1b2c3d4"
}
Error Handling
403 Forbidden on metrics endpoint
403 Forbidden on metrics endpoint
Your Ahrefs plan may not include API access to Site Explorer. Verify your subscription tier supports API calls at Ahrefs → Subscription.
Inconsistent DR across calls
Inconsistent DR across calls
Domain Rating updates asynchronously in Ahrefs’ index. If comparing competitors, pull all metrics in the same session to ensure consistent snapshot timing.