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

Expanding into new markets requires localized messaging. Perigon’s geographic filtering returns news by country, state, or city. This job pulls news from target markets, creates personas representing local consumer segments, runs a Focus Group to test messaging, then generates localized campaign copy. Flow: Perigon GET /all?country={code} → Mavera POST /personasPOST /focus-groupsPOST /generations → Localized copy

Code

import os, requests, time

PG_KEY = os.environ["PERIGON_API_KEY"]
PG_BASE = "https://api.goperigon.com/v1"
MV = os.environ["MAVERA_API_KEY"]
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

PRODUCT = "digital payments platform"
MARKETS = [
    {"country": "GB", "label": "United Kingdom", "currency": "GBP"},
    {"country": "DE", "label": "Germany", "currency": "EUR"},
    {"country": "JP", "label": "Japan", "currency": "JPY"},
]

for market in MARKETS:
    # 1. Fetch local news
    r = requests.get(f"{PG_BASE}/all", params={
        "apiKey": PG_KEY, "q": PRODUCT, "country": market["country"],
        "sortBy": "date", "size": 10,
    })
    if not r.ok:
        print(f"{market['label']}: API error {r.status_code}")
        continue
    articles = r.json().get("articles", [])
    print(f"\n{market['label']}: {len(articles)} articles")

    local_context = "\n".join(
        f"- [{a.get('source',{}).get('name','')}] {a.get('title','')}: {a.get('summary', a.get('description',''))[:200]}"
        for a in articles[:8]
    )

    # 2. Create local personas
    LOCAL_PERSONAS = [
        {"name": f"{market['label']} Early Adopter", "desc": f"Tech-forward consumer in {market['label']}. Uses multiple fintech apps. Price-sensitive but values UX. Local payment habits."},
        {"name": f"{market['label']} Traditional Buyer", "desc": f"Established professional in {market['label']}. Prefers banks. Skeptical of fintech. Values security and regulation compliance."},
        {"name": f"{market['label']} Small Business Owner", "desc": f"SMB owner in {market['label']}. Needs payment processing, invoicing, cross-border. Cost is primary concern."},
    ]
    persona_ids = []
    for lp in LOCAL_PERSONAS:
        p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
            "name": lp["name"], "description": lp["desc"],
        }).json()
        persona_ids.append(p["id"])
        time.sleep(0.3)

    # 3. Focus Group with local context
    fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
        "name": f"Market Entry: {market['label']}",
        "persona_ids": persona_ids,
        "questions": [
            f"What matters most when choosing a {PRODUCT} in {market['label']}?",
            f"What local alternatives do you currently use and why?",
            f"What would make you switch to a new {PRODUCT}?",
            f"How important is that the platform operates in {market['currency']}?",
        ],
        "responses_per_persona": 2,
    }).json()

    for _ in range(20):
        time.sleep(5)
        data = requests.get(f"{MV_BASE}/focus-groups/{fg['id']}", headers=MV_H).json()
        if data.get("status") == "completed":
            break

    # 4. Generate localized copy
    fg_summary = "\n".join(
        f"[{r.get('persona_id','')}] {r.get('question','')[:60]}{r.get('answer','')[:200]}"
        for r in data.get("responses", [])[:12]
    )

    copy = requests.post(f"{MV_BASE}/generations", headers=MV_H, json={
        "prompt": f"Generate localized marketing copy for {PRODUCT} entering {market['label']}.\n\n"
            f"LOCAL NEWS CONTEXT:\n{local_context}\n\n"
            f"FOCUS GROUP INSIGHTS:\n{fg_summary}\n\n"
            "Generate:\n"
            f"1. Hero headline (8 words max) — resonates with {market['label']} values\n"
            "2. Subheadline (20 words) — addresses top local concern\n"
            "3. Three feature bullets — localized benefits, not features\n"
            "4. CTA button text (4 words)\n"
            f"5. Social proof line referencing {market['label']} adoption\n\n"
            f"Currency: {market['currency']}. Tone: trustworthy, local, modern.",
    }).json()

    print(f"\n{'='*60}\nLOCALIZED COPY: {market['label']}\n{'='*60}")
    print(copy.get("output", copy.get("content", ""))[:600])

Example Output

United Kingdom: 10 articles

LOCALIZED COPY: United Kingdom
============================================================
1. HEADLINE: Payments That Move at London Speed
2. SUBHEADLINE: FCA-regulated, instant GBP settlements, and the integrations
   UK businesses actually use.
3. FEATURES:
   • Faster Payments rails — settle in seconds, not days
   • Open Banking ready — connect your high-street bank directly
   • HMRC-compatible invoicing built in
4. CTA: Start Free in GBP
5. SOCIAL PROOF: Trusted by 2,400 UK businesses from Bristol to Edinburgh.

LOCALIZED COPY: Germany
============================================================
1. HEADLINE: Zahlungen, Die Einfach Funktionieren
2. SUBHEADLINE: BaFin-konform, SEPA-Sofortüberweisung, und die Integrationen
   die deutsche Unternehmen tatsächlich nutzen.

Error Handling

Some country codes return few results. Broaden the query or remove sourceGroup filter. For APAC markets, try region instead of country.
Generated copy may default to USD. Explicitly include the target currency in the prompt and add "Do NOT mention USD" if needed.
Focus groups are async. The polling loop waits up to 100 seconds. Increase for complex multi-persona groups.