import os, requests, time
WS = os.environ["WISTIA_API_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
WS_BASE = "https://api.wistia.com"
MV_BASE = "https://app.mavera.io/api/v1"
WS_H = {"Authorization": f"Bearer {WS}", "Accept": "application/json"}
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
# 1. Fetch medias with their customizations (CTAs)
medias = requests.get(f"{WS_BASE}/v1/medias.json", headers=WS_H, params={
"per_page": 50, "sort_by": "play_count", "sort_direction": 0,
}).json()
cta_videos = []
for media in medias:
hashed_id = media.get("hashed_id", "")
customizations = media.get("embed_options", {})
cta = customizations.get("call_to_action", {}) or customizations.get("postRollCTA", {})
if not cta:
continue
# 2. Get stats for this media
stats = requests.get(
f"{WS_BASE}/v1/stats/medias/{hashed_id}.json", headers=WS_H
).json()
play_count = stats.get("play_count", 0)
cta_clicks = cta.get("clicks", 0)
cta_ctr = round(cta_clicks / max(play_count, 1) * 100, 2)
cta_videos.append({
"name": media.get("name", "Untitled"),
"hashed_id": hashed_id,
"duration": media.get("duration", 0),
"plays": play_count,
"cta_text": cta.get("text", ""),
"cta_url": cta.get("url", ""),
"cta_type": cta.get("type", "text"),
"cta_time": cta.get("time", "end"),
"cta_clicks": cta_clicks,
"cta_ctr": cta_ctr,
})
time.sleep(0.2)
print(f"Found {len(cta_videos)} videos with CTAs")
# 3. Sort by CTR for analysis
cta_videos.sort(key=lambda x: x["cta_ctr"])
# 4. Create Focus Group personas
persona_ids = []
for name, desc in [
("Impulse Clicker", "Clicks CTAs that create urgency or curiosity. Responds to 'limited time,' 'see inside,' and action verbs. Ignores generic 'learn more' buttons. Mobile-first viewer who needs the CTA to be thumb-friendly."),
("Deliberate Researcher", "Only clicks CTAs after watching the full video. Needs the CTA to match the video's promise exactly. Distrusts 'bait-and-switch' where the CTA leads somewhere unrelated. Values specificity over urgency."),
("Skeptical Executive", "Senior decision-maker watching to evaluate vendors. Will only click if the CTA offers something they can't get elsewhere — a demo, a calculator, an exclusive report. Ignores 'contact us' and 'subscribe.'"),
("Content Binger", "Watches 5+ videos in a session. CTAs interrupt their flow. Will only click if the CTA offers a natural next step in their learning journey, not a sales redirect."),
] :
p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
"name": name, "description": desc,
}).json()
persona_ids.append(p["id"])
time.sleep(0.3)
# 5. Build CTA performance summary
cta_block = "\n\n".join(
f"VIDEO: \"{v['name']}\"\n"
f" CTA Text: \"{v['cta_text']}\"\n"
f" CTA URL: {v['cta_url']}\n"
f" Placement: {v['cta_type']} at {v['cta_time']} | Plays: {v['plays']:,} | "
f"Clicks: {v['cta_clicks']} | CTR: {v['cta_ctr']}%"
for v in cta_videos[:8]
)
# 6. Run Focus Group
fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
"name": "CTA Performance Optimization",
"persona_ids": persona_ids,
"questions": [
f"Review these video CTAs and their click-through rates. For each, explain why you would or wouldn't click:\n\n{cta_block}",
"Rewrite the 3 lowest-performing CTA texts to maximize YOUR click probability. Explain what you changed and why.",
"Where in the video should the CTA appear? At the end (post-roll)? Mid-video? As an overlay? Why does placement matter to you?",
"What CTA format would make you most likely to click: text button, image banner, or interactive annotation? Why?",
"If you've already decided you're interested in the product, what CTA text would make you convert immediately?",
],
"responses_per_persona": 2,
}).json()
for _ in range(20):
time.sleep(5)
fg_data = requests.get(f"{MV_BASE}/focus-groups/{fg['id']}", headers=MV_H).json()
if fg_data.get("status") == "completed":
break
# 7. Output
print("\nCTA PERFORMANCE × FOCUS GROUP")
print("=" * 60)
print(f"{'Video':<35} {'CTA Text':<25} {'Plays':>7} {'CTR':>7}")
print("-" * 60)
for v in cta_videos[:8]:
print(f" {v['name'][:33]:<35} {v['cta_text'][:23]:<25} {v['plays']:>7,} {v['cta_ctr']:>6.2f}%")
print("\nFOCUS GROUP RESPONSES:")
for resp in fg_data.get("responses", []):
print(f"\n[{resp.get('persona_name', '?')}] {resp.get('question', '')[:55]}...")
print(f" → {resp.get('answer', '')[:400]}")