> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mavera.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Explorer → Trending Topics

> Discover trending content with Ahrefs Content Explorer and validate angles with Mavera Focus Groups

### Scenario

Use the Content Explorer to find trending content in your niche — articles with high social shares, referring domains, and estimated traffic. Filter for content published in the last 90 days to catch emerging trends, then create personas representing the audiences engaging with that content and validate content angles through a focus group before investing in production.

### Architecture

```mermaid theme={"dark"}
flowchart LR
    A["Ahrefs /v3/content-explorer/search"] --> B["Parse JSON"]
    B --> C["Filter high-engagement articles"]
    C --> D["POST /api/v1/personas"]
    D --> E["POST /api/v1/focus-groups"]
```

### Code

<CodeGroup>
  ```python Python theme={"dark"}
  import os, requests, time
  from datetime import datetime, timedelta

  AH = os.environ["AHREFS_API_TOKEN"]
  MV = os.environ["MAVERA_API_KEY"]
  MB, TOPIC = "https://app.mavera.io/api/v1", "AI content marketing"
  AH_H = {"Authorization": f"Bearer {AH}", "Accept": "application/json"}
  MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

  cutoff = (datetime.utcnow() - timedelta(days=90)).strftime("%Y-%m-%d")
  resp = requests.get("https://api.ahrefs.com/v3/content-explorer/search", headers=AH_H, params={
      "query": TOPIC, "mode": "title", "limit": 100,
      "order_by": "referring_domains:desc",
      "select": "title,url,published_at,organic_traffic,referring_domains,facebook_shares",
  })
  resp.raise_for_status()
  articles = resp.json().get("articles", [])
  trending = sorted(
      [a for a in articles if a.get("published_at", "") >= cutoff
       and (a.get("referring_domains", 0) >= 5 or a.get("facebook_shares", 0) >= 50)],
      key=lambda a: a.get("referring_domains", 0), reverse=True)
  print(f"Found {len(trending)} trending articles for '{TOPIC}'\n")

  personas = []
  for seg in ["B2B SaaS content manager", "freelance SEO consultant", "VP Marketing"]:
      p = requests.post(f"{MB}/personas", headers=MH, json={
          "name": f"Reader: {seg}",
          "description": f"Searches '{TOPIC}'. Engages with high-share content. Role: {seg}.",
      }).json()
      personas.append(p["id"])
      time.sleep(0.3)

  concepts = [f"'{a['title']}' — {a.get('referring_domains', 0)} sites linked"
              for a in trending[:5]]
  fg = requests.post(f"{MB}/focus-groups", headers=MH, json={
      "name": f"Trending: {TOPIC}", "persona_ids": personas,
      "questions": [
          "Which angle first?\n" + "\n".join(f"{i+1}. {c}" for i, c in enumerate(concepts)),
          "What's missing from current coverage of this topic?",
          "Would you share this with your team? Why or why not?",
      ], "responses_per_persona": 2,
  }).json()

  for _ in range(30):
      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", [])[:9]:
      print(f"[{r.get('persona_id', '?')}] {r.get('answer', '')[:300]}\n")
  ```

  ```javascript JavaScript theme={"dark"}
  const AH = process.env.AHREFS_API_TOKEN, MV = process.env.MAVERA_API_KEY;
  const MB = "https://app.mavera.io/api/v1", TOPIC = "AI content marketing";
  const AH_H = { Authorization: `Bearer ${AH}`, Accept: "application/json" };
  const MH = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };

  const cutoff = new Date(Date.now() - 90 * 86400000).toISOString().slice(0, 10);
  const params = new URLSearchParams({
    query: TOPIC, mode: "title", limit: "100", order_by: "referring_domains:desc",
    select: "title,url,published_at,organic_traffic,referring_domains,facebook_shares",
  });
  const resp = await fetch(
    `https://api.ahrefs.com/v3/content-explorer/search?${params}`, { headers: AH_H });
  const articles = (await resp.json()).articles || [];
  const trending = articles
    .filter((a) => (a.published_at || "") >= cutoff
      && (a.referring_domains >= 5 || a.facebook_shares >= 50))
    .sort((a, b) => b.referring_domains - a.referring_domains);
  console.log(`Found ${trending.length} trending articles for '${TOPIC}'\n`);

  const segments = ["B2B SaaS content manager", "freelance SEO consultant", "VP Marketing"];
  const pids = [];
  for (const seg of segments) {
    const p = await fetch(`${MB}/personas`, { method: "POST", headers: MH,
      body: JSON.stringify({ name: `Reader: ${seg}`,
        description: `Searches '${TOPIC}'. High-share content. Role: ${seg}.` }),
    }).then((r) => r.json());
    pids.push(p.id);
    await new Promise((r) => setTimeout(r, 300));
  }

  const concepts = trending.slice(0, 5).map((a) =>
    `'${a.title}' — ${a.referring_domains} sites linked`);
  const fg = await fetch(`${MB}/focus-groups`, { method: "POST", headers: MH,
    body: JSON.stringify({
      name: `Trending: ${TOPIC}`, persona_ids: pids,
      questions: ["Which angle first?\n" + concepts.map((c, i) => `${i+1}. ${c}`).join("\n"),
        "What's missing from current coverage?", "Would you share this with your team? Why?"],
      responses_per_persona: 2,
    }),
  }).then((r) => r.json());

  let data;
  for (let i = 0; i < 30; 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, 9))
    console.log(`[${r.persona_id}] ${(r.answer || "").slice(0, 300)}\n`);
  ```
</CodeGroup>

### Example Output

```json theme={"dark"}
{
  "trending_articles_found": 34,
  "top_article": {
    "title": "How AI Is Replacing Traditional Content Calendars",
    "referring_domains": 47, "facebook_shares": 892, "organic_traffic": 3200
  },
  "focus_group_highlights": [
    { "persona": "B2B SaaS content manager", "preferred_angle": "#2 — AI replacing calendars" },
    { "persona": "VP Marketing", "preferred_angle": "#4 — ROI measurement for AI content" }
  ]
}
```

### Error Handling

<AccordionGroup>
  <Accordion title="Empty results for niche topics">Content Explorer indexes broadly but may miss very niche topics. Broaden your query or remove the `mode: title` filter to search full text instead.</Accordion>
  <Accordion title="Social share counts lagging">Facebook and Twitter share counts update asynchronously and may lag by 24-48 hours. Use referring domains as the primary engagement signal for recent content.</Accordion>
</AccordionGroup>
