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

LinkedIn Campaign Manager reports performance by industry, job function, and seniority — but this data lives in spreadsheets. This job pulls analytics pivoted by these dimensions, identifies the top-performing segments (highest CTR and engagement), then uses Mave to write content briefs tailored to each winning segment. Instead of guessing what content to create, you let real campaign data tell you.

Architecture

Code

import os, requests, time

LI = os.environ["LINKEDIN_ACCESS_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
LI_BASE = "https://api.linkedin.com/rest"
MV_BASE = "https://app.mavera.io/api/v1"
LI_H = {"Authorization": f"Bearer {LI}", "LinkedIn-Version": "202401", "X-Restli-Protocol-Version": "2.0.0"}
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

CAMPAIGN_URN = "urn:li:sponsoredCampaign:200000001"

# 1. Pull analytics pivoted by industry
pivots = ["MEMBER_INDUSTRY", "MEMBER_JOB_FUNCTION", "MEMBER_SENIORITY"]
all_segments = []

for pivot in pivots:
    r = requests.get(f"{LI_BASE}/adAnalytics",
        headers=LI_H,
        params={
            "q": "analytics",
            "pivot": pivot,
            "dateRange.start.year": 2025, "dateRange.start.month": 1, "dateRange.start.day": 1,
            "dateRange.end.year": 2025, "dateRange.end.month": 12, "dateRange.end.day": 31,
            "timeGranularity": "ALL",
            "campaigns[0]": CAMPAIGN_URN,
            "fields": "impressions,clicks,costInLocalCurrency,externalWebsiteConversions",
        })
    if r.status_code == 429:
        time.sleep(int(r.headers.get("Retry-After", 60)))
        continue
    r.raise_for_status()

    for el in r.json().get("elements", []):
        impressions = el.get("impressions", 0)
        clicks = el.get("clicks", 0)
        if impressions < 100:
            continue
        ctr = clicks / impressions if impressions else 0
        conversions = el.get("externalWebsiteConversions", 0)
        all_segments.append({
            "pivot": pivot,
            "value": el.get("pivotValue", "Unknown"),
            "impressions": impressions,
            "clicks": clicks,
            "ctr": round(ctr * 100, 2),
            "conversions": conversions,
            "spend": el.get("costInLocalCurrency", 0),
        })
    time.sleep(0.5)

# 2. Rank by CTR, take top segments
top = sorted(all_segments, key=lambda x: -x["ctr"])[:6]

# 3. Generate content briefs via Mave
for seg in top:
    brief = requests.post(f"{MV_BASE}/mave/chat", headers=MV_H, json={
        "message": f"""Write a content brief for this high-performing LinkedIn audience segment.

SEGMENT: {seg['value']} ({seg['pivot'].replace('MEMBER_', '').replace('_', ' ').title()})
PERFORMANCE: {seg['impressions']:,} impressions | {seg['clicks']:,} clicks | CTR: {seg['ctr']}% | {seg['conversions']} conversions | ${seg['spend']:,.2f} spend

Produce:
1. Why this segment responds (hypotheses based on role/industry/seniority)
2. Content brief: topic, angle, format (whitepaper / blog / video / carousel)
3. Headline options (3)
4. Key messages and proof points to include
5. Distribution strategy (organic LinkedIn + paid amplification)
6. Recommended content length and CTA"""
    }).json()

    print(f"\n{'='*50}")
    print(f"SEGMENT: {seg['value']} | CTR: {seg['ctr']}% | Clicks: {seg['clicks']:,}")
    print(f"{'='*50}")
    print(brief.get("content", "")[:600])

Example Output

==================================================
SEGMENT: Information Technology | CTR: 3.42% | Clicks: 1,847
==================================================
## Content Brief: IT Leaders & Digital Transformation

### Why This Segment Responds
IT leaders are actively evaluating tools that reduce manual processes.
Your ad's "60% faster" claim maps to their OKRs around operational efficiency.

### Brief
- Topic: "The Hidden Cost of Manual Reporting in IT Organizations"
- Format: Gated whitepaper (LinkedIn lead gen form)
- Angle: Quantified pain — tie manual hours to opportunity cost

### Headlines
1. "Your IT Team Spends 12 Hours/Week on Reports Nobody Reads"
2. "How [Company] Cut Reporting Time by 60% — Without New Headcount"
3. "The CFO Wants Faster Insights. Here's How IT Delivers."

### Distribution
- Organic: 3-part LinkedIn carousel summarizing key findings
- Paid: Sponsored Content targeting IT directors + VPs, 201-1000 employees

Error Handling

LinkedIn analytics data can lag 24–48 hours. Don’t expect same-day metrics. Schedule this job to run on T+2 data.
Pivot values like MEMBER_INDUSTRY return LinkedIn’s internal taxonomy codes (e.g., urn:li:industry:4). Map them via GET /industries for human-readable names.
Segments with under 100 impressions produce unreliable CTR. The code filters these out.

All LinkedIn Marketing jobs

Mave Agent