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

You’re evaluating potential influencer partners for a brand campaign. Instead of relying on follower counts and CPMs, this job searches for each influencer’s recent YouTube content, runs Video Analysis on their top videos, and has Mave evaluate brand alignment across message tone, audience fit, visual style, and content quality. The result is an influencer scorecard that measures creative quality and brand fit — not vanity metrics.

Architecture

Code

import os, requests, time

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"}

BRAND_GUIDELINES = """
Brand tone: Approachable, expert, optimistic. Never cynical or sarcastic.
Visual style: Clean, bright, modern. Avoid cluttered frames or dark aesthetics.
Audience: 25-40, professionals, health-conscious.
Deal-breakers: Profanity, controversial opinions, competitor endorsements, clickbait.
"""

INFLUENCERS = [
    {"name": "FitnessCreator1", "channel_id": "UC_CHANNEL_ID_1"},
    {"name": "NutritionGuru", "channel_id": "UC_CHANNEL_ID_2"},
    {"name": "WellnessVlogger", "channel_id": "UC_CHANNEL_ID_3"},
]

scorecards = []

for influencer in INFLUENCERS:
    # 1. Search for recent videos by channel (100 quota units)
    search = requests.get(f"{YT_BASE}/search", params={
        "key": YT, "channelId": influencer["channel_id"],
        "type": "video", "part": "snippet",
        "maxResults": 5, "order": "date",
    }).json()

    if not search.get("items"):
        print(f"No videos found for {influencer['name']}")
        continue

    video_ids = [item["id"]["videoId"] for item in search["items"]]

    # 2. Get video stats (1 quota unit)
    details = requests.get(f"{YT_BASE}/videos", params={
        "key": YT, "id": ",".join(video_ids),
        "part": "snippet,statistics,contentDetails",
    }).json()

    video_scores = []
    for video in (details.get("items") or [])[:3]:
        vid_id = video["id"]
        stats = video.get("statistics", {})

        # 3. Upload to Mavera and analyze
        upload = requests.post(f"{MV_BASE}/assets", headers=MV_H, json={
            "url": f"https://www.youtube.com/watch?v={vid_id}",
            "name": f"{influencer['name']}{video['snippet']['title'][:40]}",
            "type": "video",
        }).json()

        analysis = requests.post(f"{MV_BASE}/video-analysis", headers=MV_H, json={
            "asset_id": upload["id"],
            "analysis_types": [
                "emotional_arc", "pacing", "visual_complexity",
                "cognitive_load", "hook_score", "brand_safety",
            ],
        }).json()

        for _ in range(30):
            time.sleep(3)
            status = requests.get(
                f"{MV_BASE}/video-analysis/{analysis['id']}", headers=MV_H
            ).json()
            if status.get("status") == "completed":
                break

        r = status.get("results", {})
        video_scores.append({
            "title": video["snippet"]["title"][:50],
            "views": int(stats.get("viewCount", 0)),
            "hook": r.get("hook_score", {}).get("score", 0),
            "emotion": r.get("emotional_arc", {}).get("intensity_avg", 0),
            "brand_safe": r.get("brand_safety", {}).get("score", 0),
            "pacing": r.get("pacing", {}).get("score", 0),
        })
        time.sleep(1)

    # 4. Brand alignment evaluation via Mave
    scores_text = "\n".join(
        f"- \"{v['title']}\" — views: {v['views']:,}, hook: {v['hook']}/100, "
        f"emotion: {v['emotion']:.1f}/10, brand-safe: {v['brand_safe']}/100, pacing: {v['pacing']:.1f}/10"
        for v in video_scores
    )

    alignment = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
        "message": f"""Evaluate influencer "{influencer['name']}" for brand partnership.

BRAND GUIDELINES:
{BRAND_GUIDELINES}

VIDEO ANALYSIS SCORES:
{scores_text}

Score 1-100 on:
1. Brand tone alignment
2. Visual style match
3. Audience overlap potential
4. Content quality consistency
5. Risk level (100 = lowest risk)

Overall recommendation: PARTNER / CONSIDER / PASS
Explain each score with evidence from the video analyses.""",
    }).json()

    avg_hook = sum(v["hook"] for v in video_scores) / len(video_scores) if video_scores else 0
    avg_safe = sum(v["brand_safe"] for v in video_scores) / len(video_scores) if video_scores else 0

    scorecards.append({
        "name": influencer["name"],
        "videos_analyzed": len(video_scores),
        "avg_hook": round(avg_hook, 1),
        "avg_brand_safety": round(avg_safe, 1),
        "assessment": alignment.get("content", "")[:600],
    })

# 5. Print scorecards
print("INFLUENCER CONTENT ANALYSIS")
print("=" * 60)
for sc in scorecards:
    print(f"\n{sc['name']} ({sc['videos_analyzed']} videos analyzed)")
    print(f"  Avg Hook: {sc['avg_hook']}/100 | Avg Brand Safety: {sc['avg_brand_safety']}/100")
    print(f"  {sc['assessment'][:500]}")

Example Output

INFLUENCER CONTENT ANALYSIS
============================================================

FitnessCreator1 (3 videos analyzed)
  Avg Hook: 82.3/100 | Avg Brand Safety: 91.0/100
  RECOMMENDATION: PARTNER
  - Tone alignment: 88/100 — energetic and positive, no sarcasm
  - Visual style: 85/100 — clean studio setup, bright lighting, modern graphics
  - Audience overlap: 79/100 — 25-35 demo, professional tone
  - Quality consistency: 90/100 — all 3 videos maintain high production value
  - Risk level: 92/100 — no profanity, no controversial content found

NutritionGuru (3 videos analyzed)
  Avg Hook: 71.0/100 | Avg Brand Safety: 74.0/100
  RECOMMENDATION: CONSIDER
  - Tone alignment: 72/100 — mostly expert tone but occasional sarcasm
  - Visual style: 65/100 — kitchen setting is good but cluttered backgrounds
  - Risk level: 68/100 — one video contained unverified health claims
  - Action: Request content guidelines agreement before partnership

WellnessVlogger (3 videos analyzed)
  Avg Hook: 45.7/100 | Avg Brand Safety: 58.0/100
  RECOMMENDATION: PASS
  - Tone alignment: 40/100 — cynical commentary style conflicts with brand
  - Risk level: 52/100 — two videos mention competitor products favorably

Error Handling

YouTube search requires channelId (starts with UC), not username. Use channels.list?forUsername= to resolve usernames to channel IDs if needed (costs 1 quota unit).
Each influencer costs ~101 quota units (1 search + 1 details). Three influencers = 303 units. For 20+ influencers, batch across days or use multiple API keys.
Mavera’s brand_safety analysis checks visual and audio content but cannot verify factual claims. Cross-reference health/financial claims manually for regulated industries.

YouTube Integration

Video Analysis