Scenario
Understand what content works for competitors — which pages drive the most organic traffic and where messaging gaps exist. Pullurl_organic for a competitor, send to Mave for gap analysis, then validate your differentiators with a focus group.
Architecture
Code
import os, requests, csv, io, time
SR, MV = os.environ["SEMRUSH_API_KEY"], os.environ["MAVERA_API_KEY"]
MB = "https://app.mavera.io/api/v1"
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
COMP = "competitor.com"
resp = requests.get("https://api.semrush.com/", params={
"type": "url_organic", "key": SR, "domain": COMP,
"database": "us", "display_limit": 50, "display_sort": "tr_desc",
"export_columns": "Ur,Fl,Fk,Fp,Nq,Td",
})
reader = csv.reader(io.StringIO(resp.text), delimiter=";")
next(reader)
pages = [{"url": r[0], "traffic": int(r[1] or 0), "keywords": int(r[2] or 0),
"top_kw": r[4]} for r in reader if len(r) >= 6]
page_block = "\n".join(f"- {p['url']} | traffic: {p['traffic']} | top: \"{p['top_kw']}\""
for p in sorted(pages, key=lambda p: -p["traffic"])[:25])
mave = requests.post(f"{MB}/mave/chat", headers=MH, json={
"message": f"Analyze competitor content gaps.\n\nCOMPETITOR: {COMP}\n"
f"TOP PAGES:\n{page_block}\n\nAnalyze: 1) Content themes 2) Gaps "
f"3) Messaging patterns 4) Our opportunities 5) 5 article concepts",
}).json()
print(mave.get("content", "")[:1500])
fg = requests.post(f"{MB}/focus-groups", headers=MH, json={
"name": f"Audit: {COMP}",
"auto_personas": {"count": 3, "description": "B2B marketing managers evaluating content tools"},
"questions": [
"Rank: 1) AI personas from real data 2) Pre-publish focus groups 3) Brand voice extraction",
"What's missing? What would make you switch tools?",
f"What would make you trust our content over {COMP}'s?",
], "responses_per_persona": 2,
}).json()
for _ in range(24):
time.sleep(5)
data = requests.get(f"{MB}/focus-groups/{fg['id']}", headers=MH).json()
if data.get("status") == "completed": break
for r in data.get("responses", [])[:6]:
print(f"[{r.get('persona_id','?')}] {r.get('answer','')[:250]}\n")
const SR = process.env.SEMRUSH_API_KEY, MV = process.env.MAVERA_API_KEY;
const MB = "https://app.mavera.io/api/v1";
const MH = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
const COMP = "competitor.com";
const params = new URLSearchParams({
type: "url_organic", key: SR, domain: COMP,
database: "us", display_limit: "50", display_sort: "tr_desc",
export_columns: "Ur,Fl,Fk,Fp,Nq,Td",
});
const text = await fetch(`https://api.semrush.com/?${params}`).then((r) => r.text());
const pages = text.trim().split("\n").slice(1).map((line) => {
const c = line.split(";");
return c.length >= 6 ? { url: c[0], traffic: parseInt(c[1]) || 0, topKw: c[4] } : null;
}).filter(Boolean).sort((a, b) => b.traffic - a.traffic);
const block = pages.slice(0, 25).map((p) => `- ${p.url} | traffic: ${p.traffic} | "${p.topKw}"`).join("\n");
const mave = await fetch(`${MB}/mave/chat`, { method: "POST", headers: MH,
body: JSON.stringify({
message: `Competitor gaps.\nCOMPETITOR: ${COMP}\nPAGES:\n${block}\nAnalyze: 1) Themes 2) Gaps 3) Messaging 4) Opportunities 5) 5 concepts`,
}),
}).then((r) => r.json());
console.log((mave.content || "").slice(0, 1500));
const fg = await fetch(`${MB}/focus-groups`, { method: "POST", headers: MH,
body: JSON.stringify({
name: `Audit: ${COMP}`,
auto_personas: { count: 3, description: "B2B marketers evaluating content tools" },
questions: ["Rank: 1) AI personas 2) Pre-publish focus groups 3) Brand voice extraction",
"What's missing? What would make you switch?",
"What would make you trust our content over theirs?"],
responses_per_persona: 2,
}),
}).then((r) => r.json());
let data;
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
data = await fetch(`${MB}/focus-groups/${fg.id}`, { headers: MH }).then((r) => r.json());
if (data.status === "completed") break;
}
for (const r of (data.responses || []).slice(0, 6))
console.log(`[${r.persona_id}] ${(r.answer || "").slice(0, 250)}\n`);
Example Output
## Themes: SEO guides (38%), tool comparisons (22%), industry reports (18%)
## Opportunities
1. Persona-driven SEO — no competitor covers audience intelligence. We own it.
2. Pre-publish validation — they A/B test after launch. Focus groups pre-launch
is a unique differentiator.
[per_auto_01] #1: Focus group validation before publishing. Pre-publish testing
with structured questions is genuinely different.
Error Handling
ERROR 50 :: NOTHING FOUND
ERROR 50 :: NOTHING FOUND
The competitor domain may lack organic data in the selected database. Try a different regional database or verify domain spelling.
Traffic estimates are modeled
Traffic estimates are modeled
SEMrush traffic numbers are estimates based on position and CTR models. Use for relative comparison, not absolute counts.
URL encoding
URL encoding
Some URLs in the response may contain encoded characters. Decode before using in further API calls.