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

# Segment Overlap Analysis

> Pull all Klaviyo segments with member counts, identify overlaps, and use Mave Agent to recommend a simplified segmentation strategy

### Scenario

Over time, you've created 20+ segments in Klaviyo — "VIP", "High CLV", "Frequent Buyers", "Loyal Customers" — and many of them overlap significantly. A customer might be in 5 segments at once, receiving redundant messaging. You pull all segments with member counts, identify overlaps, and send the data to Mave for analysis. The result is a simplified segmentation strategy that eliminates redundancy.

### Architecture

```mermaid theme={"dark"}
flowchart LR
A["Klaviyo GET /api/segments"] --> B["Identify likely overlaps"] --> C["POST /api/v1/mave/chat"] --> D["Simplified segmentation recommendations"]
```

### Code

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

  KL_KEY = os.environ["KLAVIYO_API_KEY"]
  MV = os.environ["MAVERA_API_KEY"]
  MB = "https://app.mavera.io/api/v1"
  MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
  KH = {
      "Authorization": f"Klaviyo-API-Key {KL_KEY}",
      "Content-Type": "application/json",
      "revision": "2024-10-15",
  }

  segments = []
  url = "https://a.klaviyo.com/api/segments"
  params = {"fields[segment]": "name,definition,created,updated,is_active,profile_count"}

  for page_num in range(3):
      r = requests.get(url, headers=KH, params=params if page_num == 0 else None)
      if r.status_code == 429:
          time.sleep(int(r.headers.get("Retry-After", 10)))
          continue
      r.raise_for_status()
      data = r.json()
      segments.extend(data.get("data", []))
      url = data.get("links", {}).get("next")
      if not url:
          break
      params = None
      time.sleep(0.5)

  print(f"Found {len(segments)} segments\n")

  segment_info = []
  for seg in segments:
      attrs = seg.get("attributes", {})
      segment_info.append({
          "id": seg["id"],
          "name": attrs.get("name", ""),
          "count": attrs.get("profile_count", 0),
          "active": attrs.get("is_active", True),
          "definition": str(attrs.get("definition", ""))[:200],
          "created": attrs.get("created", "")[:10],
          "updated": attrs.get("updated", "")[:10],
      })

  segment_info.sort(key=lambda s: s["count"], reverse=True)
  total_profiles = sum(s["count"] for s in segment_info)

  segment_block = "\n".join(
      f"- **{s['name']}**: {s['count']:,} profiles | Active: {s['active']} | Created: {s['created']}\n"
      f"  Definition: {s['definition'][:150]}{'...' if len(s['definition']) > 150 else ''}"
      for s in segment_info
  )

  mave = requests.post(f"{MB}/mave/chat", headers=MH, json={
      "message": f"""Analyze our Klaviyo segments for redundancy and recommend a simplified segmentation strategy.

  CURRENT SEGMENTS ({len(segment_info)} total, {total_profiles:,} total profile memberships):

  {segment_block}

  Analyze:
  1. Which segments likely have significant overlap? (based on names, definitions, and member counts)
  2. Which segments are redundant and could be merged? Suggest specific merges.
  3. Are there gaps — behavioral groups that should have segments but don't?
  4. Recommend a simplified structure with max 8-10 segments. Name each and describe its purpose.
  5. Which segments are stale (created long ago, rarely updated) and should be archived?
  6. How should these segments map to email/SMS flows?

  Goal: Reduce segment count by 40-60% while maintaining targeting precision.""",
  }).json()

  print("--- Segment Overlap Analysis ---")
  print(mave.get("content", "")[:3000])
  ```

  ```javascript JavaScript theme={"dark"}
  const KL_KEY = process.env.KLAVIYO_API_KEY;
  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 KH = { Authorization: `Klaviyo-API-Key ${KL_KEY}`, "Content-Type": "application/json", revision: "2024-10-15" };

  const segments = [];
  let url = "https://a.klaviyo.com/api/segments?fields[segment]=name,definition,created,updated,is_active,profile_count";
  for (let i = 0; i < 3; i++) {
    const res = await fetch(url, { headers: KH });
    if (res.status === 429) { await new Promise((r) => setTimeout(r, parseInt(res.headers.get("Retry-After") || "10") * 1000)); continue; }
    const data = await res.json();
    segments.push(...(data.data || []));
    url = data.links?.next;
    if (!url) break;
    await new Promise((r) => setTimeout(r, 500));
  }

  console.log(`Found ${segments.length} segments\n`);

  const segInfo = segments
    .map((s) => ({
      name: s.attributes?.name || "", count: s.attributes?.profile_count || 0,
      active: s.attributes?.is_active ?? true, definition: String(s.attributes?.definition || "").slice(0, 200),
      created: (s.attributes?.created || "").slice(0, 10),
    }))
    .sort((a, b) => b.count - a.count);

  const total = segInfo.reduce((s, seg) => s + seg.count, 0);
  const block = segInfo.map((s) => `- **${s.name}**: ${s.count.toLocaleString()} profiles | Active: ${s.active} | Created: ${s.created}\n  Def: ${s.definition.slice(0, 150)}`).join("\n");

  const mave = await fetch(`${MB}/mave/chat`, { method: "POST", headers: MH,
    body: JSON.stringify({
      message: `Analyze ${segInfo.length} Klaviyo segments (${total.toLocaleString()} total memberships) for overlap.\n\n${block}\n\nAnalyze: 1) Overlaps 2) Merge candidates 3) Gaps 4) Simplified 8-10 segment structure 5) Stale segments 6) Flow mapping.\n\nGoal: reduce by 40-60%.`,
    }),
  }).then((r) => r.json());

  console.log("--- Segment Analysis ---");
  console.log((mave.content || "").slice(0, 3000));
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
--- Segment Overlap Analysis ---

## Likely Overlaps
| Segments | Est. Overlap | Recommendation |
|----------|-------------|----------------|
| "VIP" + "High CLV" + "Loyal" | ~70% overlap | Merge into "Top Customers" |
| "Recent Buyers" + "Active 30d" | ~85% overlap | "Recent Buyers" subsumes both |
| "Newsletter" + "All Subscribers" | ~95% overlap | Archive "All Subscribers" |

## Recommended Simplified Structure (8 segments)
1. **Top Customers** — CLV > $500, 3+ orders (merge VIP + High CLV + Loyal)
2. **Growth Customers** — 2+ orders, CLV $100-500
3. **New Customers** — First order in last 30 days
4. **At Risk** — Churn risk > 50%, was active in last 90d
5. **Win Back** — No order in 90+ days, had 2+ previous orders
6. **Browse Abandoners** — Viewed products, no cart/purchase in 7d
7. **Cart Abandoners** — Active cart, no purchase in 24h
8. **Engaged Non-Buyers** — Opens/clicks emails, never purchased

## Stale Segments to Archive
- "Holiday 2024 Shoppers" (created 2024-11-15, never updated)
- "Beta Testers" (created 2024-03-01, 12 profiles)
- "Imported List 3" (created 2024-06-01, unknown purpose)

## Flow Mapping
| Segment | Flow | Cadence |
|---------|------|---------|
| New Customers | Welcome + education | 5 emails / 14 days |
| At Risk | Win-back | 3 emails / 10 days |
| Top Customers | VIP exclusives | 1 email / week |
| Browse Abandoners | Product nudge | 2 emails / 3 days |
```

### Error Handling

<AccordionGroup>
  <Accordion title="Segment definitions are complex">Klaviyo segment definitions use a nested JSON structure for conditions. The code truncates to 200 chars for readability. For precise overlap analysis, compare the actual condition logic, not just names.</Accordion>
  <Accordion title="profile_count is eventual">The `profile_count` field updates asynchronously. It may lag behind real-time segment membership by minutes to hours. For exact counts, query the Profiles endpoint filtered by segment.</Accordion>
  <Accordion title="Pagination for large segment lists">Klaviyo returns segments paginated. The code fetches up to 3 pages (\~300 segments). If you have more, increase the page loop or use a higher `page[size]`.</Accordion>
</AccordionGroup>

***

## What's Next

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

  <Card title="Flow Content Refresh" icon="arrows-rotate" href="/integrations/klaviyo/flow-content-refresh">
    Rewrite underperforming flow content
  </Card>

  <Card title="Product Affinity Focus Group" icon="cart-shopping" href="/integrations/klaviyo/product-affinity-focus-group">
    Cross-sell validation with Likert + NPS
  </Card>

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