> ## 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.

# Domain Rating Comparison → Competitive Positioning

> Compare domain authority across competitors with Ahrefs and craft positioning messaging with Mavera

### 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. The `metrics` endpoint returns domain rating, total backlinks, referring domains, and organic traffic estimates for any target.

### Architecture

```mermaid theme={"dark"}
flowchart LR
    A["Ahrefs /v3/site-explorer/metrics"] --> B["Compare domain_rating, backlinks, referring_domains"]
    B --> C["POST /api/v1/mave/chat"]
    C --> D["POST /api/v1/brand-voices"]
```

### Code

<CodeGroup>
  ```python Python theme={"dark"}
  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')}")
  ```

  ```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";
  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}`);
  ```
</CodeGroup>

### Example Output

```json theme={"dark"}
{
  "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

<AccordionGroup>
  <Accordion title="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](https://app.ahrefs.com/user/subscription).</Accordion>
  <Accordion title="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.</Accordion>
</AccordionGroup>
