Skip to main content

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.

Scenario

Your competitors organize their YouTube content into playlists that reveal their content strategy — topic clusters, sequencing, and narrative arcs. This job pulls a competitor’s playlists and their items, then sends the full structure to Mave for strategic analysis. Mave identifies what content themes the competitor prioritizes, how they sequence viewer journeys, and where their playlist strategy has gaps your brand could exploit. The result is a reverse-engineered content strategy with actionable recommendations.

Architecture

Code

import os, requests

YT = os.environ["YOUTUBE_API_KEY"]
MV = os.environ["MAVERA_API_KEY"]
YT_BASE = "https://www.googleapis.com/youtube/v3"
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

COMPETITOR_CHANNEL_ID = "UC_COMPETITOR_CHANNEL_ID"

# 1. Get all playlists (1 quota unit per page)
playlists_data = requests.get(f"{YT_BASE}/playlists", params={
    "key": YT, "channelId": COMPETITOR_CHANNEL_ID,
    "part": "snippet,contentDetails", "maxResults": 25,
}).json()

if "error" in playlists_data:
    raise SystemExit(f"YouTube API error: {playlists_data['error']['message']}")

playlists = []
for pl in playlists_data.get("items", []):
    playlists.append({
        "id": pl["id"],
        "title": pl["snippet"]["title"],
        "description": pl["snippet"].get("description", "")[:200],
        "video_count": pl["contentDetails"]["itemCount"],
        "published": pl["snippet"]["publishedAt"][:10],
    })

print(f"Found {len(playlists)} playlists")

# 2. Get items for each playlist (1 quota unit per page per playlist)
playlist_details = []
for pl in playlists[:10]:
    items_data = requests.get(f"{YT_BASE}/playlistItems", params={
        "key": YT, "playlistId": pl["id"],
        "part": "snippet", "maxResults": 20,
    }).json()

    videos = []
    for item in items_data.get("items", []):
        s = item["snippet"]
        videos.append({
            "position": s["position"],
            "title": s["title"],
            "description": s.get("description", "")[:150],
        })

    playlist_details.append({
        "title": pl["title"],
        "description": pl["description"],
        "video_count": pl["video_count"],
        "published": pl["published"],
        "videos": videos,
    })

# 3. Build playlist map for Mave
playlist_block = ""
for pd in playlist_details:
    playlist_block += f"\n### Playlist: \"{pd['title']}\" ({pd['video_count']} videos, created {pd['published']})\n"
    playlist_block += f"Description: {pd['description']}\n"
    playlist_block += "Videos (in order):\n"
    for v in pd["videos"]:
        playlist_block += f"  {v['position']+1}. {v['title']}\n"

# 4. Strategic analysis via Mave
analysis = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
    "message": f"""Analyze this competitor's YouTube playlist strategy.

COMPETITOR PLAYLISTS:
{playlist_block}

Produce:
1. **Content Themes**: What topics does this competitor prioritize? Rank by investment (playlist count × video count).
2. **Sequencing Strategy**: How do they order videos within playlists? Do they follow a learning path, chronological release, or engagement-optimized sequence?
3. **Narrative Arcs**: Do playlists tell a story? Identify any viewer journey patterns (awareness → consideration → conversion).
4. **Content Gaps**: What obvious topics are MISSING from their playlist strategy?
5. **Recommendations**: 3-5 playlist concepts our brand should create to fill gaps the competitor hasn't covered.
6. **Counter-Programming**: For each competitor playlist, suggest a playlist we could create that directly competes but differentiates.""",
}).json()

print("\nPLAYLIST-BASED CONTENT STRATEGY")
print("=" * 60)
print(f"Competitor channel: {COMPETITOR_CHANNEL_ID}")
print(f"Playlists analyzed: {len(playlist_details)}")
print(f"Total videos across playlists: {sum(pd['video_count'] for pd in playlist_details)}")
print("\n" + analysis.get("content", "")[:2500])

Example Output

PLAYLIST-BASED CONTENT STRATEGY
============================================================
Competitor channel: UC_COMPETITOR_CHANNEL_ID
Playlists analyzed: 8
Total videos across playlists: 142

## Content Themes (by investment)
1. **Product Tutorials** (3 playlists, 48 videos) — heaviest investment
2. **Customer Stories** (2 playlists, 31 videos) — social proof focus
3. **Industry Trends** (1 playlist, 22 videos) — thought leadership
4. **Webinar Replays** (1 playlist, 28 videos) — repurposed live content
5. **Company Culture** (1 playlist, 13 videos) — employer branding

## Sequencing Strategy
- Tutorial playlists follow a learning path: basics → intermediate → advanced
- Customer stories are ordered by company size (SMB → Enterprise)
- Trend playlists are reverse-chronological (newest first)

## Content Gaps
1. **No comparison/vs. content** — they avoid direct competitor mentions
2. **No community content** — no user-generated or collaborative videos
3. **No Shorts playlists** — all content is 5-30min long-form
4. **No FAQ/troubleshooting** — support content is absent

## Recommended Playlists for Our Channel
1. "Us vs. [Competitor]" — Direct comparison playlist (they won't make this)
2. "60-Second Tips" — Shorts playlist filling their short-form gap
3. "Community Showcase" — Feature customer content they ignore
4. "Ask Us Anything" — FAQ format they haven't adopted
5. "Behind the Product" — Transparency content they lack

Error Handling

Private playlists are not returned by the API. Unlisted playlists are also hidden. The analysis only covers public content.
Each playlists.list page = 1 unit, each playlistItems.list page = 1 unit. 10 playlists × 1 page = 11 total units. For channels with 50+ playlists, paginate with nextPageToken and batch across runs.
The playlistItems endpoint returns max 50 items per page. Playlists with 100+ videos need pagination. The code fetches the first 20 items per playlist — sufficient for sequencing analysis.

YouTube Integration

Mave Agent