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

# Video Engagement × Mavera Scoring Correlation

> Discover which Mavera creative metric best predicts real Vimeo engagement — plays, finish rate, likes, and comments

### Scenario

You have Vimeo engagement data (plays, finishes, average percent watched, engagement graphs) and Mavera Video Analysis scores — but you don't know which Mavera metric actually predicts real-world engagement. This job pulls engagement stats for your video library from Vimeo, runs Video Analysis on the same videos, then asks Mave to correlate the two datasets: "Which Mavera metric best predicts real engagement?" The result is a data-driven answer to which creative qualities drive actual viewer behavior — so you can optimize future videos for the metrics that matter.

### Architecture

```mermaid theme={"dark"}
flowchart LR
    A["Vimeo GET /me/videos (stats)"] --> B["Mavera POST /video-analysis"] --> C[Combine engagement + analysis scores] --> D["POST /mave/chat (correlation)"] --> E[Predictive metric ranking]
```

### Code

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

  VM = os.environ["VIMEO_ACCESS_TOKEN"]
  MV = os.environ["MAVERA_API_KEY"]
  VM_BASE = "https://api.vimeo.com"
  MV_BASE = "https://app.mavera.io/api/v1"
  VM_H = {"Authorization": f"Bearer {VM}", "Accept": "application/vnd.vimeo.*+json;version=3.4"}
  MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

  # 1. Pull videos with engagement stats
  resp = requests.get(f"{VM_BASE}/me/videos", headers=VM_H, params={
      "per_page": 50, "sort": "plays", "direction": "desc",
      "fields": "uri,name,link,duration,stats,metadata.connections.likes.total,"
                "metadata.connections.comments.total",
  }).json()

  videos = []
  for v in resp.get("data", []):
      vid_id = v["uri"].split("/")[-1]
      stats = v.get("stats", {})
      videos.append({
          "id": vid_id, "name": v["name"], "link": v["link"],
          "duration": v.get("duration", 0),
          "plays": stats.get("plays", 0),
          "finishes": stats.get("finishes", 0),
          "avg_watched": round(stats.get("finishes", 0) / max(stats.get("plays", 1), 1) * 100, 1),
          "likes": v.get("metadata", {}).get("connections", {}).get("likes", {}).get("total", 0),
          "comments": v.get("metadata", {}).get("connections", {}).get("comments", {}).get("total", 0),
      })

  print(f"Pulled engagement data for {len(videos)} videos")

  # 2. Run Mavera Video Analysis on top 15
  combined = []
  for video in videos[:15]:
      upload = requests.post(f"{MV_BASE}/assets", headers=MV_H, json={
          "url": video["link"], "name": video["name"][:80], "type": "video",
      }).json()

      analysis = requests.post(f"{MV_BASE}/video-analysis", headers=MV_H, json={
          "asset_id": upload["id"],
          "analysis_types": [
              "message_clarity", "emotional_impact", "hook_score",
              "behavioral_effectiveness", "pacing", "cognitive_load",
          ],
      }).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", {})
      combined.append({
          **video,
          "clarity": r.get("message_clarity", {}).get("score", 0),
          "emotion": r.get("emotional_impact", {}).get("score", 0),
          "hook": r.get("hook_score", {}).get("score", 0),
          "behavior": r.get("behavioral_effectiveness", {}).get("score", 0),
          "pacing_score": r.get("pacing", {}).get("score", 0),
          "cog_load": r.get("cognitive_load", {}).get("average", 0),
      })
      time.sleep(1)

  # 3. Build correlation dataset for Mave
  data_block = "\n".join(
      f"Video: \"{c['name'][:40]}\" | "
      f"Plays: {c['plays']:,} | Finish%: {c['avg_watched']}% | Likes: {c['likes']} | Comments: {c['comments']} || "
      f"Clarity: {c['clarity']} | Emotion: {c['emotion']} | Hook: {c['hook']} | "
      f"Behavior: {c['behavior']} | Pacing: {c['pacing_score']} | CogLoad: {c['cog_load']}"
      for c in combined
  )

  correlation = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
      "message": f"""Analyze the correlation between Mavera creative scores and real Vimeo engagement.

  DATASET ({len(combined)} videos — engagement metrics || Mavera scores):
  {data_block}

  Produce:
  1. **Best Predictor**: Which single Mavera metric most strongly predicts real engagement (plays, finish rate, likes)?
  2. **Metric-by-Metric Correlation**: For each Mavera metric, how well does it predict each engagement metric? (strong/moderate/weak/none)
  3. **Surprising Findings**: Any metrics that DON'T correlate with engagement despite seeming important?
  4. **Composite Formula**: Suggest a weighted combination of Mavera metrics that best predicts finish rate
  5. **Actionable Rule**: "If you optimize for [X Mavera metric], you'll see the biggest lift in [Y engagement metric]"
  6. **Outliers**: Videos where Mavera scores and engagement diverge — what explains the gap?""",
  }).json()

  print("VIDEO ENGAGEMENT × MAVERA SCORING CORRELATION")
  print("=" * 65)
  print(f"{'Video':<35} {'Plays':>8} {'Finish%':>8} {'Emotion':>8} {'Hook':>6} {'Clarity':>8}")
  print("-" * 65)
  for c in combined:
      print(f"  {c['name'][:33]:<35} {c['plays']:>8,} {c['avg_watched']:>7.1f}% "
            f"{c['emotion']:>7} {c['hook']:>5} {c['clarity']:>7}")
  print("\n" + correlation.get("content", "")[:2000])
  ```

  ```javascript JavaScript theme={"dark"}
  const VM = process.env.VIMEO_ACCESS_TOKEN;
  const MV = process.env.MAVERA_API_KEY;
  const VM_BASE = "https://api.vimeo.com";
  const MV_BASE = "https://app.mavera.io/api/v1";
  const VM_H = { Authorization: `Bearer ${VM}`, Accept: "application/vnd.vimeo.*+json;version=3.4" };
  const MV_H = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };

  // 1. Pull engagement stats
  const resp = await fetch(
    `${VM_BASE}/me/videos?per_page=50&sort=plays&direction=desc` +
    `&fields=uri,name,link,duration,stats,metadata.connections.likes.total,metadata.connections.comments.total`,
    { headers: VM_H }
  ).then(r => r.json());

  const videos = (resp.data || []).map(v => {
    const stats = v.stats || {};
    const plays = stats.plays || 0;
    const finishes = stats.finishes || 0;
    return {
      id: v.uri.split("/").pop(), name: v.name, link: v.link,
      duration: v.duration || 0, plays, finishes,
      avgWatched: plays > 0 ? Math.round(finishes / plays * 1000) / 10 : 0,
      likes: v.metadata?.connections?.likes?.total || 0,
      comments: v.metadata?.connections?.comments?.total || 0,
    };
  });

  console.log(`Pulled engagement for ${videos.length} videos`);

  // 2. Mavera analysis on top 15
  const combined = [];
  for (const video of videos.slice(0, 15)) {
    const upload = await fetch(`${MV_BASE}/assets`, {
      method: "POST", headers: MV_H,
      body: JSON.stringify({ url: video.link, name: video.name.slice(0, 80), type: "video" }),
    }).then(r => r.json());

    const analysis = await fetch(`${MV_BASE}/video-analysis`, {
      method: "POST", headers: MV_H,
      body: JSON.stringify({
        asset_id: upload.id,
        analysis_types: ["message_clarity", "emotional_impact", "hook_score", "behavioral_effectiveness", "pacing", "cognitive_load"],
      }),
    }).then(r => r.json());

    let status;
    for (let i = 0; i < 30; i++) {
      await new Promise(r => setTimeout(r, 3000));
      status = await fetch(`${MV_BASE}/video-analysis/${analysis.id}`, { headers: MV_H }).then(r => r.json());
      if (status.status === "completed") break;
    }

    const r = status.results || {};
    combined.push({
      ...video,
      clarity: r.message_clarity?.score || 0, emotion: r.emotional_impact?.score || 0,
      hook: r.hook_score?.score || 0, behavior: r.behavioral_effectiveness?.score || 0,
      pacingScore: r.pacing?.score || 0, cogLoad: r.cognitive_load?.average || 0,
    });
    await new Promise(r => setTimeout(r, 1000));
  }

  // 3. Correlation analysis
  const dataBlock = combined.map(c =>
    `Video: "${c.name.slice(0, 40)}" | Plays: ${c.plays.toLocaleString()} | Finish%: ${c.avgWatched}% | ` +
    `Likes: ${c.likes} | Comments: ${c.comments} || ` +
    `Clarity: ${c.clarity} | Emotion: ${c.emotion} | Hook: ${c.hook} | Behavior: ${c.behavior}`
  ).join("\n");

  const correlation = await fetch(`${MV_BASE}/mave/chat`, {
    method: "POST", headers: MV_H,
    body: JSON.stringify({
      message: `Correlate Mavera scores vs real Vimeo engagement.\n\nDATASET (${combined.length} videos):\n${dataBlock}\n\nProduce:\n1. Best single predictor of engagement\n2. Metric-by-metric correlation strength\n3. Surprising non-correlations\n4. Composite formula for finish rate\n5. Actionable optimization rule\n6. Outliers and explanations`,
    }),
  }).then(r => r.json());

  console.log("VIDEO ENGAGEMENT × MAVERA SCORING CORRELATION");
  console.log("=".repeat(65));
  combined.forEach(c =>
    console.log(`  ${c.name.slice(0, 33).padEnd(35)} ${String(c.plays.toLocaleString()).padStart(8)} ` +
      `${(c.avgWatched + "%").padStart(8)} ${String(c.emotion).padStart(8)} ${String(c.hook).padStart(6)} ${String(c.clarity).padStart(8)}`)
  );
  console.log("\n" + (correlation.content || "").slice(0, 2000));
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
VIDEO ENGAGEMENT × MAVERA SCORING CORRELATION
=================================================================
Video                                 Plays  Finish%  Emotion   Hook  Clarity
-----------------------------------------------------------------
  Q1 Brand Campaign — Feel the D      84,200   72.3%      94     87       91
  Customer Story — Acme Corp Tra      42,100   68.1%      82     76       88
  Product Demo — Enterprise Dash      31,500   41.2%      45     62       79
  How-To: Getting Started in 5 M      28,700   81.4%      52     71       93
  Webinar Replay — State of the       18,300   23.8%      38     41       72

## Correlation Analysis

### Best Single Predictor
**Hook Score** is the strongest predictor of plays (r=0.82). Videos with
hook scores above 75 average 3.2x more plays than those below 60.

### Metric-by-Metric Correlation
| Mavera Metric    | → Plays  | → Finish% | → Likes |
|------------------|----------|-----------|---------|
| Hook Score       | Strong   | Moderate  | Strong  |
| Emotional Impact | Strong   | Strong    | Strong  |
| Message Clarity  | Moderate | Strong    | Weak    |
| Behavioral Eff.  | Moderate | Moderate  | Moderate|
| Pacing           | Weak     | Strong    | Weak    |
| Cognitive Load   | Weak     | Moderate  | None    |

### Surprising Finding
**Message Clarity** strongly predicts finish rate (r=0.78) but only weakly
predicts plays. Clear videos retain viewers but don't attract them.
You need hook score to get clicks and clarity to keep them watching.

### Composite Formula for Finish Rate
`Predicted Finish% ≈ (Clarity × 0.4) + (Emotion × 0.3) + (Pacing × 0.2) + (Hook × 0.1)`

### Actionable Rule
Optimize for **hook score** to maximize distribution (plays), and
**message clarity** to maximize retention (finish rate). These are
different creative muscles — treat the first 5 seconds and the body
as separate optimization targets.
```

### Error Handling

<AccordionGroup>
  <Accordion title="Stats availability">Vimeo stats (`plays`, `finishes`) require a Vimeo Pro, Business, or Premium account. Free accounts only get `plays`. The `finishes` metric may return 0 for very new videos without sufficient data.</Accordion>
  <Accordion title="Sample size for correlation">15 videos is a minimum viable sample for directional correlation. For statistically significant results, analyze 50+ videos. The code samples the top 15 by plays — consider random sampling for unbiased results.</Accordion>
  <Accordion title="Engagement graph endpoint">For per-second engagement data, use `GET /videos/{id}/stats` with `fields=engagement_graph`. This returns a frame-by-frame attention curve that can be paired with Mavera's emotional arc for deeper correlation.</Accordion>
</AccordionGroup>

***

## What's Next

<CardGroup cols={2}>
  <Card title="Vimeo Integration" icon="circle-play" href="/integrations/vimeo">
    Back to Vimeo integration overview
  </Card>

  <Card title="Caption Content Extraction" icon="closed-captioning" href="/integrations/vimeo/caption-content-extraction">
    Extract repurposable content from transcripts
  </Card>

  <Card title="Video Analysis API" icon="chart-bar" href="/api-reference/video-analysis">
    Full reference for POST /api/v1/video-analysis
  </Card>

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