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

# Economic Indicator → Focus Group

### Scenario

GDP growth, CPI inflation, and unemployment rates affect every consumer segment differently. A retiree on fixed income reacts to 5% CPI differently than a tech worker with stock options. This job pulls the latest economic indicators, creates demographic personas (retiree, new graduate, small business owner, dual-income family), and runs a Focus Group where each persona reacts to the actual data — revealing how to message products during different economic conditions.

**Flow:** Alpha Vantage `GET ?function=REAL_GDP` + `CPI` + `UNEMPLOYMENT` → Mavera `POST /personas` → `POST /focus-groups` → Economic messaging insights

### Code

<CodeGroup>
  ```python Python theme={"dark"}
  import os, requests, time

  AV_KEY = os.environ["ALPHA_VANTAGE_KEY"]
  AV_BASE = "https://www.alphavantage.co/query"
  MV = os.environ["MAVERA_API_KEY"]
  MV_BASE = "https://app.mavera.io/api/v1"
  MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

  # 1. Fetch economic indicators
  indicators = {}
  for func, label in [("REAL_GDP", "GDP"), ("CPI", "CPI"), ("UNEMPLOYMENT", "Unemployment")]:
      r = requests.get(AV_BASE, params={"function": func, "interval": "quarterly" if func == "REAL_GDP" else "monthly", "apikey": AV_KEY})
      r.raise_for_status()
      data = r.json().get("data", [])
      recent = data[:4]
      indicators[label] = {
          "latest": recent[0] if recent else {},
          "trend": [{"date": d.get("date",""), "value": d.get("value","")} for d in recent],
      }
      latest = recent[0] if recent else {}
      print(f"{label}: {latest.get('value','N/A')} ({latest.get('date','N/A')})")
      time.sleep(15)

  # 2. Build economic snapshot
  snapshot = "\n".join(
      f"**{label}**: {d['latest'].get('value','N/A')} (as of {d['latest'].get('date','N/A')})\n"
      f"  Trend: {' → '.join(t['value'] for t in reversed(d['trend']))}"
      for label, d in indicators.items()
  )

  # 3. Create demographic personas
  DEMOGRAPHICS = [
      {"name": "Retiree on Fixed Income", "desc": "Age 68. Pension + Social Security. $52K/year. Inflation directly erodes purchasing power. Risk-averse. Watches news daily."},
      {"name": "Recent College Graduate", "desc": "Age 23. First job, $55K salary. $38K student debt. Optimistic but financially stressed. Rents. No investments yet."},
      {"name": "Small Business Owner", "desc": "Age 42. Restaurant owner, 12 employees. Revenue $1.2M. Margins thin (8%). Labor costs and food costs top concerns."},
      {"name": "Dual-Income Suburban Family", "desc": "Ages 36/38. Combined $180K. Mortgage, two kids, saving for college. Feel upper-middle but stretched. Inflation hits grocery and childcare."},
  ]
  persona_ids = []
  for demo in DEMOGRAPHICS:
      p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
          "name": f"Econ: {demo['name']}", "description": demo["desc"],
      }).json()
      persona_ids.append(p["id"])
      time.sleep(0.3)

  # 4. Focus Group
  fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
      "name": "Economic Indicator Reactions",
      "persona_ids": persona_ids,
      "questions": [
          f"Here are the latest economic numbers:\n{snapshot}\n\nHow do these numbers make you feel about your financial situation?",
          "Based on these numbers, will you spend more, less, or the same in the next 3 months? On what?",
          "If a financial services company approached you right now, what message would resonate?",
          "What's the one economic indicator you personally watch most? Why?",
      ],
      "responses_per_persona": 2,
  }).json()

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

  # 5. Print responses
  print(f"\n{'='*60}\nECONOMIC FOCUS GROUP RESULTS\n{'='*60}")
  print(f"Indicators: {snapshot}\n")
  for resp in data.get("responses", []):
      pid = resp.get("persona_id", "")
      idx = persona_ids.index(pid) if pid in persona_ids else -1
      name = DEMOGRAPHICS[idx]["name"] if 0 <= idx < len(DEMOGRAPHICS) else "Unknown"
      print(f"[{name}] Q: {resp.get('question','')[:80]}")
      print(f"  A: {resp.get('answer','')[:350]}\n")
  ```

  ```javascript JavaScript theme={"dark"}
  const AV_KEY = process.env.ALPHA_VANTAGE_KEY;
  const AV_BASE = "https://www.alphavantage.co/query";
  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" };

  // 1. Economic indicators
  const indicators = {};
  for (const [func, label, interval] of [
    ["REAL_GDP", "GDP", "quarterly"], ["CPI", "CPI", "monthly"], ["UNEMPLOYMENT", "Unemployment", "monthly"]
  ]) {
    const r = await fetch(`${AV_BASE}?function=${func}&interval=${interval}&apikey=${AV_KEY}`);
    const data = (await r.json()).data || [];
    const recent = data.slice(0, 4);
    indicators[label] = { latest: recent[0] || {}, trend: recent.map(d => ({ date: d.date, value: d.value })) };
    console.log(`${label}: ${recent[0]?.value || "N/A"} (${recent[0]?.date || "N/A"})`);
    await new Promise(r => setTimeout(r, 15000));
  }

  // 2. Snapshot
  const snapshot = Object.entries(indicators).map(([label, d]) =>
    `**${label}**: ${d.latest.value||"N/A"} (${d.latest.date||"N/A"})\n  Trend: ${d.trend.map(t=>t.value).reverse().join(" → ")}`).join("\n");

  // 3. Personas
  const DEMOGRAPHICS = [
    { name: "Retiree on Fixed Income", desc: "Age 68. Pension + SS. $52K. Inflation erodes purchasing power." },
    { name: "Recent Graduate", desc: "Age 23. $55K salary. $38K debt. Optimistic but stressed. Rents." },
    { name: "Small Business Owner", desc: "Age 42. Restaurant, 12 employees. $1.2M revenue, 8% margins." },
    { name: "Dual-Income Family", desc: "Ages 36/38. $180K combined. Mortgage, 2 kids. Stretched." },
  ];
  const personaIds = [];
  for (const demo of DEMOGRAPHICS) {
    const p = await fetch(`${MV_BASE}/personas`, { method: "POST", headers: MV_H,
      body: JSON.stringify({ name: `Econ: ${demo.name}`, description: demo.desc }),
    }).then(r => r.json());
    personaIds.push(p.id);
    await new Promise(r => setTimeout(r, 300));
  }

  // 4. Focus Group
  const fg = await fetch(`${MV_BASE}/focus-groups`, { method: "POST", headers: MV_H,
    body: JSON.stringify({ name: "Economic Indicator Reactions", persona_ids: personaIds,
      questions: [
        `Latest numbers:\n${snapshot}\n\nHow do these affect your financial situation?`,
        "Spend more, less, or same next 3 months? On what?",
        "What message from a financial company would resonate right now?",
        "Which indicator do you watch most? Why?",
      ], responses_per_persona: 2 }),
  }).then(r => r.json());

  let data;
  for (let i = 0; i < 25; 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;
  }

  console.log(`\n${"=".repeat(60)}\nECONOMIC FOCUS GROUP RESULTS`);
  for (const resp of data.responses || []) {
    const idx = personaIds.indexOf(resp.persona_id);
    const name = idx >= 0 ? DEMOGRAPHICS[idx].name : "Unknown";
    console.log(`[${name}] Q: ${(resp.question||"").slice(0,80)}`);
    console.log(`  A: ${(resp.answer||"").slice(0,350)}\n`);
  }
  ```
</CodeGroup>

### Example Output

```text theme={"dark"}
GDP: 22038.236 (2025-10-01)
CPI: 315.648 (2026-01-01)
Unemployment: 4.1 (2026-02-01)

ECONOMIC FOCUS GROUP RESULTS
============================================================
[Retiree on Fixed Income] Q: How do these numbers affect your financial situation?
  A: CPI at 315 means my grocery bill is up 20% from 2020 but my
     pension COLA was only 3.2%. I'm making trade-offs I shouldn't
     have to make — generic medications, store brands, skipping the
     annual trip. GDP growth means nothing when my income is fixed.

[Recent Graduate] Q: Spend more, less, or same? On what?
  A: Same on rent because I have no choice. Less on eating out —
     switched to meal prep. More on skill-building (online courses)
     because 4.1% unemployment won't last. Need to be irreplaceable.

[Small Business Owner] Q: What message would resonate?
  A: "We'll help you keep your margins without cutting staff."
     That's it. Don't tell me the economy is growing — my food
     costs are up 15% and I can't raise menu prices again.
```

### Error Handling

<AccordionGroup>
  <Accordion title="Rate limits across indicators">3 indicator calls at 15s intervals = 45s. On free tier, this uses 3 of 25 daily calls. Cache indicators — they update monthly/quarterly.</Accordion>
  <Accordion title="Data format">GDP returns in billions, CPI is an index (base 1982-84=100), Unemployment is a percentage. Include units in Focus Group context so personas interpret correctly.</Accordion>
  <Accordion title="Focus Group timeout">Economic questions are complex. Allow up to 2 minutes for completion. The polling loop handles this with 25 × 5s iterations.</Accordion>
</AccordionGroup>
