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

# Audience Interest Tags → Content Generation

> Pull Mailchimp interest categories and subscriber counts to generate targeted email content per interest group using Mavera Generate with optional brand voice

### Scenario

Mailchimp audiences have interest categories — topics subscribers opted into like "Product Updates", "Industry News", "Tips & Tutorials", "Case Studies". You pull the interest categories and subscriber counts per interest, then generate targeted email content per interest group, applying your brand voice. The result is personalized email content matched to declared subscriber preferences.

### Architecture

```mermaid theme={"dark"}
flowchart LR
A["GET /lists/{id}/interest-categories"] --> B["GET specific interests"] --> C["POST /api/v1/generations per interest"] --> D["Interest-personalized email content"]
```

### Code

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

  MC_KEY = os.environ["MAILCHIMP_API_KEY"]
  MC_DC = os.environ["MAILCHIMP_DC"]
  MV = os.environ["MAVERA_API_KEY"]
  MB = "https://app.mavera.io/api/v1"
  MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
  MC_BASE = f"https://{MC_DC}.api.mailchimp.com/3.0"
  mc_auth = ("anystring", MC_KEY)

  lists_r = requests.get(f"{MC_BASE}/lists", auth=mc_auth, params={"count": 1})
  LIST_ID = lists_r.json()["lists"][0]["id"]

  cats_r = requests.get(f"{MC_BASE}/lists/{LIST_ID}/interest-categories", auth=mc_auth)
  cats_r.raise_for_status()
  categories = cats_r.json().get("categories", [])

  interests = []
  for cat in categories:
      cat_id = cat["id"]
      int_r = requests.get(
          f"{MC_BASE}/lists/{LIST_ID}/interest-categories/{cat_id}/interests",
          auth=mc_auth,
      )
      for interest in int_r.json().get("interests", []):
          interests.append({
              "id": interest["id"],
              "name": interest["name"],
              "category": cat.get("title", ""),
              "subscribers": interest.get("subscriber_count", 0),
          })
      time.sleep(0.3)

  interests.sort(key=lambda x: x["subscribers"], reverse=True)
  print(f"Found {len(interests)} interests across {len(categories)} categories\n")

  BRAND_VOICE_ID = os.environ.get("BRAND_VOICE_ID", "")

  for interest in interests[:6]:
      prompt = (
          f"Generate a complete email for subscribers interested in '{interest['name']}' "
          f"(category: {interest['category']}, {interest['subscribers']} subscribers).\n\n"
          f"Include:\n"
          f"1. Subject line (max 50 characters)\n"
          f"2. Preview text (max 90 characters)\n"
          f"3. Email body (200-300 words) with:\n"
          f"   - Compelling opening hook\n"
          f"   - 2-3 key points relevant to this interest\n"
          f"   - Clear CTA\n"
          f"4. Alternative subject line for A/B testing\n\n"
          f"Tone: Informative but engaging. These subscribers opted in specifically for "
          f"'{interest['name']}' content, so be relevant and respect their preference."
      )

      payload = {"prompt": prompt}
      if BRAND_VOICE_ID:
          payload["brand_voice_id"] = BRAND_VOICE_ID

      gen = requests.post(f"{MB}/generations", headers=MH, json=payload).json()

      print(f"{'='*50}")
      print(f"Interest: {interest['name']} ({interest['subscribers']} subs)")
      print(f"Category: {interest['category']}")
      print(f"{'='*50}")
      print(gen.get("output", gen.get("content", ""))[:600])
      print()
      time.sleep(0.5)
  ```

  ```javascript JavaScript theme={"dark"}
  const MC_KEY = process.env.MAILCHIMP_API_KEY;
  const MC_DC = process.env.MAILCHIMP_DC;
  const MV = process.env.MAVERA_API_KEY;
  const MB = "https://app.mavera.io/api/v1";
  const MH = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
  const MC_BASE = `https://${MC_DC}.api.mailchimp.com/3.0`;
  const mcAuth = "Basic " + Buffer.from(`anystring:${MC_KEY}`).toString("base64");
  const BRAND_VOICE_ID = process.env.BRAND_VOICE_ID || "";

  const listsRes = await fetch(`${MC_BASE}/lists?count=1`, { headers: { Authorization: mcAuth } }).then((r) => r.json());
  const LIST_ID = listsRes.lists[0].id;

  const catsRes = await fetch(`${MC_BASE}/lists/${LIST_ID}/interest-categories`, { headers: { Authorization: mcAuth } }).then((r) => r.json());

  const interests = [];
  for (const cat of catsRes.categories || []) {
    const intRes = await fetch(`${MC_BASE}/lists/${LIST_ID}/interest-categories/${cat.id}/interests`, { headers: { Authorization: mcAuth } }).then((r) => r.json());
    for (const interest of intRes.interests || []) {
      interests.push({ id: interest.id, name: interest.name, category: cat.title || "", subscribers: interest.subscriber_count || 0 });
    }
    await new Promise((r) => setTimeout(r, 300));
  }

  interests.sort((a, b) => b.subscribers - a.subscribers);
  console.log(`Found ${interests.length} interests\n`);

  for (const interest of interests.slice(0, 6)) {
    const payload = {
      prompt: `Generate email for '${interest.name}' subscribers (${interest.subscribers} subs, category: ${interest.category}).\n\nInclude: 1) Subject (max 50 chars) 2) Preview (max 90 chars) 3) Body 200-300 words with hook, 2-3 points, CTA 4) Alt subject for A/B.`,
    };
    if (BRAND_VOICE_ID) payload.brand_voice_id = BRAND_VOICE_ID;

    const gen = await fetch(`${MB}/generations`, { method: "POST", headers: MH,
      body: JSON.stringify(payload) }).then((r) => r.json());

    console.log(`${"=".repeat(50)}`);
    console.log(`${interest.name} (${interest.subscribers} subs) — ${interest.category}`);
    console.log((gen.output || gen.content || "").slice(0, 600));
    console.log();
    await new Promise((r) => setTimeout(r, 500));
  }
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
==================================================
Interest: Product Updates (3,200 subs)
Category: Content Preferences
==================================================
Subject: New in March: 3 features you asked for
Preview: The dashboard redesign is here — plus two surprises.

Hi there,

You asked, we built. Here's what shipped this month:

**1. Redesigned Dashboard**
Everything you track, now in one view. Custom widgets snap into
place — no more switching between 4 tabs to see your metrics.

**2. Slack Integration**
Get alerts where you already work. Set thresholds, pick channels,
done in 60 seconds.

**3. Export to PDF (yes, finally)**
One-click branded reports. Your clients will think you hired a
designer.

→ [See What's New — Full Changelog]

Alt subject: You asked for these 3 features — they're live
```

### Error Handling

<AccordionGroup>
  <Accordion title="Interest categories require audience setup">Interest categories must be created in Mailchimp → Audience → Manage Audience → Groups. If no groups exist, the API returns an empty list.</Accordion>
  <Accordion title="subscriber_count is approximate">The `subscriber_count` on interests is updated periodically, not in real time. It may lag behind actual subscription changes by up to a day.</Accordion>
  <Accordion title="Brand voice optional">If `BRAND_VOICE_ID` is not set, the Generate call uses Mavera's default voice. Create a voice first via Job 2 above for best results.</Accordion>
</AccordionGroup>

***

## What's Next

<CardGroup cols={2}>
  <Card title="Mailchimp Integration" icon="envelope" href="/integrations/mailchimp">
    Back to Mailchimp integration overview
  </Card>

  <Card title="A/B Focus Group" icon="flask-vial" href="/integrations/mailchimp/ab-focus-group">
    Understand why A/B variants win
  </Card>

  <Card title="Re-Engagement Builder" icon="rotate" href="/integrations/mailchimp/re-engagement-builder">
    Win back dormant subscribers
  </Card>

  <Card title="Generate API" icon="wand-magic-sparkles" href="/api-reference/generations">
    Full reference for POST /api/v1/generations
  </Card>
</CardGroup>
