Scenario
Pull the top-performing pages from your domain by organic traffic, analyze what makes them successful (structure, keyword targeting, topic coverage), then generate content briefs that replicate those patterns for underperforming or uncovered topics. The Ahrefstop-pages endpoint returns pages sorted by estimated organic traffic alongside the keywords driving that traffic and their positions.
Architecture
Code
import os, requests, time
AH = os.environ["AHREFS_API_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
MB, DOMAIN = "https://app.mavera.io/api/v1", "yourdomain.com"
AH_H = {"Authorization": f"Bearer {AH}", "Accept": "application/json"}
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
resp = requests.get("https://api.ahrefs.com/v3/site-explorer/top-pages", headers=AH_H, params={
"target": DOMAIN, "mode": "subdomains", "limit": 50,
"order_by": "organic_traffic:desc",
"select": "url,organic_traffic,keywords_top3,keywords_top10",
})
resp.raise_for_status()
pages = resp.json().get("pages", [])
top_block = "\n".join(
f"- {p['url']} | traffic: {p['organic_traffic']} | top3: {p.get('keywords_top3', 0)}"
for p in pages[:25])
total_traffic = sum(p["organic_traffic"] for p in pages)
analysis = requests.post(f"{MB}/mave/chat", headers=MH, json={
"message": f"Analyze top pages for {DOMAIN}.\nTraffic: {total_traffic}\n"
f"TOP PAGES:\n{top_block}\n\nIdentify: 1) Structural patterns "
f"2) Content themes 3) Keyword strategy 4) Gaps 5) 5 new concepts",
}).json()
print("=== Pattern Analysis ===")
print(analysis.get("content", "")[:1200])
for i in range(3):
gen = requests.post(f"{MB}/generations", headers=MH, json={
"prompt": f"SEO brief #{i+1} for {DOMAIN}.\nAnalysis:\n"
f"{analysis.get('content', '')[:500]}\n\nGenerate: 1) SEO title "
f"2) Meta (155 chars) 3) Primary + 3 secondary KWs "
f"4) H2/H3 outline 5) Word count 6) Internal links 7) CTA",
}).json()
print(f"\n=== Brief #{i+1} ===")
print(gen.get("output", gen.get("content", ""))[:500])
time.sleep(1)
const AH = process.env.AHREFS_API_TOKEN, MV = process.env.MAVERA_API_KEY;
const MB = "https://app.mavera.io/api/v1", DOMAIN = "yourdomain.com";
const AH_H = { Authorization: `Bearer ${AH}`, Accept: "application/json" };
const MH = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
const params = new URLSearchParams({
target: DOMAIN, mode: "subdomains", limit: "50",
order_by: "organic_traffic:desc",
select: "url,organic_traffic,keywords_top3,keywords_top10",
});
const resp = await fetch(
`https://api.ahrefs.com/v3/site-explorer/top-pages?${params}`, { headers: AH_H });
const pages = (await resp.json()).pages || [];
const block = pages.slice(0, 25).map((p) =>
`- ${p.url} | traffic: ${p.organic_traffic} | top3: ${p.keywords_top3 ?? 0}`
).join("\n");
const totalTraffic = pages.reduce((s, p) => s + p.organic_traffic, 0);
const analysis = await fetch(`${MB}/mave/chat`, { method: "POST", headers: MH,
body: JSON.stringify({
message: `Analyze top pages for ${DOMAIN}.\nTraffic: ${totalTraffic}\n`
+ `PAGES:\n${block}\n\n1) Patterns 2) Themes 3) Gaps 4) 5 new concepts`,
}),
}).then((r) => r.json());
console.log("=== Pattern Analysis ===");
console.log((analysis.content || "").slice(0, 1200));
for (let i = 0; i < 3; i++) {
const gen = await fetch(`${MB}/generations`, { method: "POST", headers: MH,
body: JSON.stringify({
prompt: `Brief #${i + 1} for ${DOMAIN}.\nAnalysis:\n`
+ `${(analysis.content || "").slice(0, 500)}\n\n`
+ `1) Title 2) Meta 3) Keywords 4) Outline 5) Word count 6) Links 7) CTA`,
}),
}).then((r) => r.json());
console.log(`\n=== Brief #${i + 1} ===`);
console.log((gen.output || gen.content || "").slice(0, 500));
await new Promise((r) => setTimeout(r, 1000));
}
Example Output
{
"pages_analyzed": 50,
"total_organic_traffic": 87420,
"dominant_theme": "how-to guides with data tables",
"sample_brief": {
"title": "How to Build a Content Testing Framework (With Templates)",
"primary_keyword": "content testing framework",
"word_count": 2500,
"h2_outline": ["Why Test Content", "The 5-Step Framework", "Tools & Templates", "Measuring Impact"]
}
}
Error Handling
401 Unauthorized
401 Unauthorized
Your Ahrefs API token is invalid, expired, or revoked. Regenerate at Ahrefs → API Keys. Bearer tokens are long-lived but can be rotated.
429 Too Many Requests
429 Too Many Requests
You’ve exceeded the 60 requests/minute rate limit. Back off for 60 seconds. In production, implement a token-bucket rate limiter shared across all Ahrefs calls.