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

# Interest Category → Content Strategy

> Pull GA4 interest category reports and use Mave Agent to research content opportunities that bridge your product with your audience's browsing interests

### Scenario

GA4 captures user interests based on browsing behavior — categories like "Technology/Software", "Business/Finance", "Travel/Adventure". You pull an interest category report, identify the top affinity categories among your visitors, and send them to Mave with the instruction to research content opportunities that bridge your product with those interests. The result is a content strategy that meets your audience where they already spend attention.

### Architecture

```mermaid theme={"dark"}
flowchart LR
    A["GA4 RunReport (interest categories)"] --> B[Top interest categories by users + engagement] --> C["POST /api/v1/mave/chat"] --> D[Content strategy bridging product with interests]
```

### Code

<CodeGroup>
  ```python Python theme={"dark"}
  import os, requests
  from google.analytics.data_v1beta import BetaAnalyticsDataClient
  from google.analytics.data_v1beta.types import (
      RunReportRequest, Dimension, Metric, DateRange, OrderBy,
  )

  PROPERTY_ID = os.environ["GA4_PROPERTY_ID"]
  MV = os.environ["MAVERA_API_KEY"]

  client = BetaAnalyticsDataClient()

  affinity_report = client.run_report(RunReportRequest(
      property=f"properties/{PROPERTY_ID}",
      dimensions=[Dimension(name="brandingInterest")],
      metrics=[
          Metric(name="totalUsers"),
          Metric(name="sessions"),
          Metric(name="engagementRate"),
          Metric(name="conversions"),
      ],
      date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
      order_bys=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="totalUsers"), desc=True)],
      limit=30,
  ))

  interests = []
  for row in affinity_report.rows:
      cat = row.dimension_values[0].value
      if cat == "(not set)":
          continue
      interests.append({
          "category": cat,
          "users": int(row.metric_values[0].value),
          "sessions": int(row.metric_values[1].value),
          "engagement": float(row.metric_values[2].value),
          "conversions": int(row.metric_values[3].value),
      })

  total_users = sum(i["users"] for i in interests) or 1

  interest_block = "\n".join(
      f"- {i['category']}: {i['users']} users ({i['users']/total_users:.0%}), "
      f"engagement: {i['engagement']:.1%}, conv: {i['conversions']}"
      for i in interests[:20]
  )

  PRODUCT_CONTEXT = "B2B marketing intelligence platform that helps teams create personas, run focus groups, and generate brand-aligned content."

  mave = requests.post(
      "https://app.mavera.io/api/v1/mave/chat",
      headers={"Authorization": f"Bearer {MV}", "Content-Type": "application/json"},
      json={"message": f"""Research content opportunities that bridge our product with our audience's interests.

  OUR PRODUCT: {PRODUCT_CONTEXT}

  AUDIENCE INTEREST CATEGORIES (from GA4, last 30 days):
  {interest_block}

  For each promising interest-product intersection:
  1. Why this interest category connects to our product
  2. Content angle (blog, webinar, case study, social series, etc.)
  3. Suggested title and hook
  4. Target keyword themes
  5. Which existing interest group this serves

  Prioritize intersections with high engagement rate AND conversion potential.
  Group into 3 tiers: immediate opportunities, medium-term content, and long-tail experiments."""},
  ).json()

  print("--- Interest-Based Content Strategy ---")
  print(mave.get("content", "")[:3000])
  print(f"\nSources: {len(mave.get('sources', []))}")
  ```

  ```javascript JavaScript theme={"dark"}
  const MV = process.env.MAVERA_API_KEY;
  const PROPERTY_ID = process.env.GA4_PROPERTY_ID;
  const KEY_FILE = JSON.parse(require("fs").readFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS, "utf8"));

  const { GoogleAuth } = require("google-auth-library");
  const auth = new GoogleAuth({
    credentials: KEY_FILE,
    scopes: ["https://www.googleapis.com/auth/analytics.readonly"],
  });
  const accessToken = await auth.getAccessToken();

  const gaRes = await fetch(
    `https://analyticsdata.googleapis.com/v1beta/properties/${PROPERTY_ID}:runReport`,
    {
      method: "POST",
      headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
      body: JSON.stringify({
        dimensions: [{ name: "brandingInterest" }],
        metrics: [
          { name: "totalUsers" }, { name: "sessions" },
          { name: "engagementRate" }, { name: "conversions" },
        ],
        dateRanges: [{ startDate: "30daysAgo", endDate: "today" }],
        orderBys: [{ metric: { metricName: "totalUsers" }, desc: true }],
        limit: 30,
      }),
    }
  ).then((r) => r.json());

  const interests = (gaRes.rows || [])
    .filter((row) => row.dimensionValues[0].value !== "(not set)")
    .map((row) => ({
      category: row.dimensionValues[0].value,
      users: parseInt(row.metricValues[0].value),
      sessions: parseInt(row.metricValues[1].value),
      engagement: parseFloat(row.metricValues[2].value),
      conversions: parseInt(row.metricValues[3].value),
    }));

  const totalUsers = interests.reduce((s, i) => s + i.users, 0) || 1;
  const interestBlock = interests.slice(0, 20)
    .map((i) => `- ${i.category}: ${i.users} users (${(i.users / totalUsers * 100).toFixed(0)}%), engagement: ${(i.engagement * 100).toFixed(1)}%, conv: ${i.conversions}`)
    .join("\n");

  const PRODUCT_CONTEXT = "B2B marketing intelligence platform for personas, focus groups, and brand-aligned content generation.";

  const mave = await fetch("https://app.mavera.io/api/v1/mave/chat", {
    method: "POST",
    headers: { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" },
    body: JSON.stringify({
      message: `Research content opportunities bridging our product with audience interests.\n\nPRODUCT: ${PRODUCT_CONTEXT}\n\nINTERESTS (GA4 30d):\n${interestBlock}\n\nFor each intersection: 1) Why it connects 2) Content angle 3) Title + hook 4) Keywords 5) Which interest group. Tier into immediate, medium-term, and experimental.`,
    }),
  }).then((r) => r.json());

  console.log("--- Interest-Based Content Strategy ---");
  console.log((mave.content || "").slice(0, 3000));
  console.log(`\nSources: ${(mave.sources || []).length}`);
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
--- Interest-Based Content Strategy ---

## Tier 1: Immediate Opportunities

### Technology/Software × Persona Intelligence
Your audience already thinks in terms of tech tooling.
→ Blog: "How AI Personas Replace 6 Months of User Research"
→ Keywords: AI persona tools, synthetic user research, automated focus groups

### Business/Finance × ROI-Driven Content
High conversion rate (3.2%) — these users evaluate tools on ROI.
→ Case study: "How [Company] Cut Content Testing Costs by 70% with Synthetic Personas"
→ Webinar: "The CFO's Guide to AI-Powered Market Research"

## Tier 2: Medium-Term Content

### Marketing/Advertising × Brand Voice
Natural overlap — your audience runs campaigns daily.
→ Series: "Brand Voice Extraction: From 50 Blog Posts to a Consistent Voice in 10 Minutes"
→ Keywords: brand voice AI, content consistency tools

## Tier 3: Long-Tail Experiments

### Travel/Adventure × Remote Research
Surprising interest category with 12% of users, 1.8% engagement rate.
→ Angle: "How Remote-First Teams Run Focus Groups Without Flying Anywhere"

Sources: 4
```

### Error Handling

<AccordionGroup>
  <Accordion title="Interest dimensions require Google Signals">The `brandingInterest` dimension requires [Google Signals](https://support.google.com/analytics/answer/9445345) to be enabled in GA4 → Admin → Data Settings → Data Collection. Without it, all values return `(not set)`.</Accordion>
  <Accordion title="Low cardinality in interest data">Smaller properties (under 10k monthly users) may have too few classified users for meaningful interest data. Extend the date range to 90 days for better coverage.</Accordion>
</AccordionGroup>

***

## What's Next

<CardGroup cols={2}>
  <Card title="GA4 Integration" icon="chart-line" href="/integrations/ga4">
    Back to GA4 integration overview
  </Card>

  <Card title="Audience Demographics → Persona Creation" icon="users" href="/integrations/ga4/audience-demographics-personas">
    Create personas from GA4 demographic data
  </Card>

  <Card title="Conversion Path → Focus Group Validation" icon="comments" href="/integrations/ga4/conversion-focus-group">
    Validate funnel drop-offs with focus groups
  </Card>

  <Card title="Mave Agent" icon="brain" href="/api-reference/mave">
    Full reference for POST /api/v1/mave/chat
  </Card>
</CardGroup>
