> ## 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.

# Geographic News → Market-Specific Messaging

### 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 /personas` → `POST /focus-groups` → `POST /generations` → Localized copy

### Code

<CodeGroup>
  ```python Python theme={"dark"}
  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])
  ```

  ```javascript JavaScript theme={"dark"}
  const PG_KEY = process.env.PERIGON_API_KEY;
  const PG_BASE = "https://api.goperigon.com/v1";
  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 PRODUCT = "digital payments platform";
  const MARKETS = [
    { country: "GB", label: "United Kingdom", currency: "GBP" },
    { country: "DE", label: "Germany", currency: "EUR" },
    { country: "JP", label: "Japan", currency: "JPY" },
  ];

  for (const market of MARKETS) {
    // 1. Local news
    const r = await fetch(
      `${PG_BASE}/all?apiKey=${PG_KEY}&q=${encodeURIComponent(PRODUCT)}&country=${market.country}&sortBy=date&size=10`);
    if (!r.ok) { console.log(`${market.label}: error ${r.status}`); continue; }
    const articles = (await r.json()).articles || [];
    console.log(`\n${market.label}: ${articles.length} articles`);

    const localContext = articles.slice(0, 8).map(a =>
      `- [${a.source?.name||""}] ${a.title||""}: ${(a.summary||a.description||"").slice(0,200)}`).join("\n");

    // 2. Local personas
    const personaIds = [];
    for (const lp of [
      { name: `${market.label} Early Adopter`, desc: `Tech-forward in ${market.label}. Multiple fintech apps. Price-sensitive.` },
      { name: `${market.label} Traditional Buyer`, desc: `Established in ${market.label}. Prefers banks. Values security.` },
      { name: `${market.label} SMB Owner`, desc: `SMB in ${market.label}. Payment processing, invoicing, cross-border.` },
    ]) {
      const p = await fetch(`${MV_BASE}/personas`, { method: "POST", headers: MV_H,
        body: JSON.stringify({ name: lp.name, description: lp.desc }),
      }).then(r => r.json());
      personaIds.push(p.id);
      await new Promise(r => setTimeout(r, 300));
    }

    // 3. Focus Group
    const fg = await fetch(`${MV_BASE}/focus-groups`, { method: "POST", headers: MV_H,
      body: JSON.stringify({ name: `Market Entry: ${market.label}`, persona_ids: personaIds,
        questions: [`What matters most for ${PRODUCT} in ${market.label}?`, `Local alternatives?`,
          `What makes you switch?`, `How important is ${market.currency} support?`],
        responses_per_persona: 2 }),
    }).then(r => r.json());

    let data;
    for (let i = 0; i < 20; i++) {
      await new Promise(r => setTimeout(r, 5000));
      data = await fetch(`${MV_BASE}/focus-groups/${fg.id}`, { headers: MV_H }).then(r => r.json());
      if (data.status === "completed") break;
    }

    const fgSummary = (data.responses || []).slice(0, 12)
      .map(r => `${(r.question||"").slice(0,60)} → ${(r.answer||"").slice(0,200)}`).join("\n");

    // 4. Localized copy
    const copy = await fetch(`${MV_BASE}/generations`, { method: "POST", headers: MV_H,
      body: JSON.stringify({ prompt: `Localized copy for ${PRODUCT} in ${market.label}.\n\nNEWS:\n${localContext}\n\nFOCUS GROUP:\n${fgSummary}\n\n1. Hero headline (8 words)\n2. Subheadline (20 words)\n3. Three feature bullets\n4. CTA (4 words)\n5. Social proof for ${market.label}\n\nCurrency: ${market.currency}. Tone: trustworthy, local.` }),
    }).then(r => r.json());

    console.log(`\n${"=".repeat(60)}\nLOCALIZED COPY: ${market.label}\n${"=".repeat(60)}`);
    console.log((copy.output || copy.content || "").slice(0, 600));
  }
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
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

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