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

When a story breaks in your industry, the first brand to publish a relevant take captures attention. This job monitors top headlines, identifies breaking stories via Mave alignment scoring, and immediately generates content pieces — a LinkedIn post, a tweet thread hook, and a blog intro — all aligned to your brand voice. Flow: NewsAPI GET /top-headlines → Mavera POST /mave/chat (alignment) → POST /generations (content) → Rapid content library

Code

import os, requests, time

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

BRAND = "B2B marketing analytics platform. Audience: CMOs and marketing directors. Tone: data-driven, authoritative, contrarian."
CATEGORY = "business"

# 1. Fetch breaking headlines
r = requests.get(f"{NA_BASE}/top-headlines", headers=NA_H, params={
    "category": CATEGORY, "country": "us", "pageSize": 15,
})
r.raise_for_status()
headlines = r.json().get("articles", [])
print(f"Fetched {len(headlines)} breaking headlines")

# 2. Score alignment via Mave
aligned = []
for article in headlines:
    check = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
        "message": f"Rate brand-news alignment (1-10).\n\nHEADLINE: {article['title']}\n"
            f"DESCRIPTION: {article.get('description','')[:300]}\nSOURCE: {article.get('source',{}).get('name','')}\n\n"
            f"BRAND: {BRAND}\n\nIf 7+: suggest angle, format, and urgency level (hours/today/this-week).",
    }).json()
    content = check.get("content", "")
    try:
        score_line = [l for l in content.split("\n") if "/10" in l][0]
        score = int("".join(c for c in score_line if c.isdigit())[:2])
    except (IndexError, ValueError):
        score = 0
    if score >= 7:
        aligned.append({"title": article["title"], "desc": article.get("description",""),
                        "source": article.get("source",{}).get("name",""),
                        "score": score, "angle": content[:400]})
    time.sleep(0.5)

print(f"Aligned: {len(aligned)} of {len(headlines)}")

# 3. Generate rapid content for top stories
for story in aligned[:3]:
    gen = requests.post(f"{MV_BASE}/generations", headers=MV_H, json={
        "prompt": f"Breaking news rapid content. Generate ALL three formats:\n\n"
            f"NEWS: {story['title']}\nDESCRIPTION: {story['desc'][:300]}\n"
            f"ANGLE: {story['angle'][:200]}\nBRAND: {BRAND}\n\n"
            "1. LINKEDIN POST (200-300 words): Hook with the news, add contrarian take, end with question.\n"
            "2. TWEET THREAD HOOK (3 tweets, 280 chars each): Thread starter that drives clicks.\n"
            "3. BLOG INTRO (150 words): SEO-optimized opening paragraph for a longer analysis piece.\n\n"
            "Tone: data-driven, authoritative. Reference the source.",
    }).json()
    print(f"\n{'='*60}\nSTORY: {story['title']} (Alignment: {story['score']}/10)")
    print(f"{'='*60}")
    print(gen.get("output", gen.get("content", ""))[:1200])

Example Output

Fetched 15 breaking headlines
Aligned: 4 of 15

STORY: Google Ads Deprecates Last-Click Attribution (Alignment: 10/10)
============================================================

1. LINKEDIN POST:
Google just deprecated last-click attribution. If your marketing team is
panicking, you were already measuring wrong.

Here's the uncomfortable truth: 73% of B2B companies still report on
last-click. They've been over-crediting bottom-funnel tactics and
under-investing in brand for years...

2. TWEET THREAD:
🧵 Google killed last-click attribution today. Most marketers are panicking.
Smart ones are relieved. Here's why ↓ (1/3)

3. BLOG INTRO:
Google's deprecation of last-click attribution isn't a technical change —
it's an admission that single-touch measurement never worked...

Error Handling

Top headlines update every 15 minutes. For true breaking news, poll on a cron. Cache previous results to avoid duplicate content generation.
If fewer than 2 stories align, broaden category or switch to /everything with industry-specific queries.
Generation may exceed platform limits (LinkedIn: 3,000 chars, Twitter: 280). Validate lengths before posting.