Scenario
Your leadership team sees the same industry headlines but interprets them differently — your CMO cares about brand impact, your CTO cares about technology shifts, your CFO worries about market risk. This job pulls today’s top headlines for your industry, then runs each story through Mavera Speak sessions with distinct executive personas. The output is a single digest where every story carries three different lenses of analysis. Flow: NewsAPIGET /top-headlines → Mavera POST /personas → POST /speak per story → Multi-perspective digest
Code
import os, requests, time, json
NA_KEY = os.environ["NEWSAPI_KEY"]
NA_BASE = "https://newsapi.org/v2"
NA_H = {"X-Api-Key": NA_KEY}
MV = os.environ["MAVERA_API_KEY"]
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
INDUSTRY = "technology"
COUNTRY = "us"
# 1. Fetch top headlines
r = requests.get(f"{NA_BASE}/top-headlines", headers=NA_H, params={
"category": INDUSTRY, "country": COUNTRY, "pageSize": 10,
})
r.raise_for_status()
articles = r.json().get("articles", [])
print(f"Fetched {len(articles)} headlines for {INDUSTRY}/{COUNTRY}")
# 2. Create executive personas
EXECS = [
{"name": "CMO Lens", "desc": "Chief Marketing Officer. Evaluates news for brand impact, competitive positioning, consumer sentiment shifts, and content opportunities."},
{"name": "CTO Lens", "desc": "Chief Technology Officer. Evaluates news for technology disruption, infrastructure implications, build-vs-buy decisions, and engineering talent market."},
{"name": "CFO Lens", "desc": "Chief Financial Officer. Evaluates news for market risk, revenue impact, cost implications, investor sentiment, and regulatory exposure."},
]
persona_ids = []
for ex in EXECS:
p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
"name": f"News Digest: {ex['name']}",
"description": ex["desc"],
}).json()
persona_ids.append({"id": p["id"], "name": ex["name"]})
time.sleep(0.3)
# 3. Run each story through each persona via Speak
digest = []
for article in articles[:7]:
story_block = f"**{article['title']}**\n{article.get('description','')}\nSource: {article.get('source',{}).get('name','')}"
perspectives = {}
for persona in persona_ids:
speak = requests.post(f"{MV_BASE}/speak", headers=MV_H, json={
"persona_id": persona["id"],
"input": [
{"role": "system", "content": f"You are a {persona['name']}. Analyze this news story in 2-3 sentences from your executive perspective. Focus on actionable implications."},
{"role": "user", "content": story_block},
],
"mode": "interview",
}).json()
answer = ""
for ex in speak.get("exchanges", speak.get("messages", [])):
if ex.get("role") == "assistant":
answer = ex["content"]
perspectives[persona["name"]] = answer[:300]
time.sleep(0.3)
digest.append({"title": article["title"], "source": article.get("source",{}).get("name",""),
"perspectives": perspectives})
# 4. Print digest
for i, story in enumerate(digest, 1):
print(f"\n{'='*60}\n{i}. {story['title']} ({story['source']})\n{'='*60}")
for lens, analysis in story["perspectives"].items():
print(f"\n [{lens}]\n {analysis}")
const NA_KEY = process.env.NEWSAPI_KEY;
const NA_BASE = "https://newsapi.org/v2";
const NA_H = { "X-Api-Key": NA_KEY };
const MV = process.env.MAVERA_API_KEY;
const MV_BASE = "https://app.mavera.io/api/v1";
const MV_H = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };
const INDUSTRY = "technology";
const COUNTRY = "us";
// 1. Headlines
const articles = (await (await fetch(
`${NA_BASE}/top-headlines?category=${INDUSTRY}&country=${COUNTRY}&pageSize=10`,
{ headers: NA_H })).json()).articles || [];
console.log(`Fetched ${articles.length} headlines for ${INDUSTRY}/${COUNTRY}`);
// 2. Executive personas
const EXECS = [
{ name: "CMO Lens", desc: "Evaluates for brand impact, positioning, sentiment shifts, content opportunities." },
{ name: "CTO Lens", desc: "Evaluates for tech disruption, infrastructure, build-vs-buy, talent market." },
{ name: "CFO Lens", desc: "Evaluates for market risk, revenue impact, cost, investor sentiment, regulation." },
];
const personaIds = [];
for (const ex of EXECS) {
const p = await fetch(`${MV_BASE}/personas`, { method: "POST", headers: MV_H,
body: JSON.stringify({ name: `News Digest: ${ex.name}`, description: ex.desc }),
}).then(r => r.json());
personaIds.push({ id: p.id, name: ex.name });
await new Promise(r => setTimeout(r, 300));
}
// 3. Speak per story × persona
const digest = [];
for (const article of articles.slice(0, 7)) {
const storyBlock = `**${article.title}**\n${article.description || ""}\nSource: ${article.source?.name || ""}`;
const perspectives = {};
for (const persona of personaIds) {
const speak = await fetch(`${MV_BASE}/speak`, { method: "POST", headers: MV_H,
body: JSON.stringify({ persona_id: persona.id, mode: "interview",
input: [
{ role: "system", content: `You are a ${persona.name}. Analyze in 2-3 sentences. Actionable implications.` },
{ role: "user", content: storyBlock },
],
}),
}).then(r => r.json());
const answer = (speak.exchanges || speak.messages || [])
.filter(e => e.role === "assistant").map(e => e.content).join(" ");
perspectives[persona.name] = answer.slice(0, 300);
await new Promise(r => setTimeout(r, 300));
}
digest.push({ title: article.title, source: article.source?.name || "", perspectives });
}
// 4. Print
for (const [i, story] of digest.entries()) {
console.log(`\n${"=".repeat(60)}\n${i + 1}. ${story.title} (${story.source})\n${"=".repeat(60)}`);
for (const [lens, analysis] of Object.entries(story.perspectives))
console.log(`\n [${lens}]\n ${analysis}`);
}
Example Output
Fetched 10 headlines for technology/us
============================================================
1. Apple Announces New AI Chip for Consumer Devices (TechCrunch)
============================================================
[CMO Lens]
Messaging window opens — "AI-powered" positioning hits mainstream. Refresh
product copy to lead with on-device intelligence before competitors adopt
the same language. Content opportunity: comparison guide.
[CTO Lens]
On-device inference shifts build calculus. Evaluate whether our cloud-first
ML pipeline should add edge deployment. Talent implication: need engineers
with NPU experience within 12 months.
[CFO Lens]
Apple's capex signals hardware margin compression. Our cloud API costs may
decrease as inference moves client-side. Watch for licensing model changes
that affect our COGS.
Error Handling
Truncated content
Truncated content
Free-tier articles return only 200 chars of content. Use
description field as primary input, or upgrade to Business for full content.Rate limits
Rate limits
Free tier: 100 req/day. This job uses 1 (headlines) + N×3 (Speak) calls to Mavera. Cache NewsAPI responses to avoid redundant calls on re-runs.
Category filtering
Category filtering
Valid categories:
business, entertainment, general, health, science, sports, technology. Use /everything with q param for custom topics.