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

# Quickstart: Focus Groups

> Create and run your first AI-powered synthetic focus group with personas and multiple question types in under 15 minutes

## What You'll Learn

In this quickstart you will:

* **Understand** synthetic focus groups: AI personas answer your questions at scale, so you get segment-level feedback without recruiting real users.
* **Gather** prerequisites: API key, workspace ID, and at least two persona IDs.
* **Create** a focus group with a name, sample size, persona list, and a short set of questions (e.g. NPS, Likert, open-ended).
* **Retrieve** the completed focus group and read aggregated results (NPS score, summaries, individual responses).
* **Interpret** the output so you can act on it (e.g. product or messaging decisions).

Focus groups are ideal for validating messaging, concepts, or product features before a full launch—with results in minutes instead of weeks.

<Info>
  **Time:** About 15 minutes (creation is quick; completion can take 1–5 minutes depending on sample size and question count). **Credits:** Roughly 50–200 credits depending on sample size and questions.
</Info>

***

## Prerequisites

<Check>**Mavera account** with an active subscription and enough credits. Focus groups typically use 50–200 credits per run.</Check>
<Check>**API key** from [Developer Settings](https://app.mavera.io/settings/developer).</Check>
<Check>**Workspace ID** for the workspace where the focus group will live. You can find it in the app URL when viewing a workspace (e.g. `app.mavera.io/workspaces/ws_abc123`) or via the workspaces API.</Check>
<Check>**At least two persona IDs** from `GET /personas`. Use personas that match your target segments (e.g. Gen Z, Millennial Professional, B2B Decision Maker).</Check>

If you don't have a workspace yet, create one in the [Mavera dashboard](https://app.mavera.io); the API can also list workspaces if your account exposes that endpoint.

***

## What Is a Synthetic Focus Group?

A **focus group** in Mavera is a single run where:

1. You define a **sample size** (e.g. 25 or 50).
2. You select **personas** (e.g. Gen Z Consumer, Millennial Professional). Each "respondent" is one of these personas.
3. You define **questions** with types such as NPS (0–10), Likert (agree/disagree), multiple choice, or open-ended.
4. Mavera **simulates** that many responses from the chosen personas and returns:
   * **Aggregated** metrics (e.g. NPS score, % promoters/detractors, average Likert).
   * **Per-question summaries** and, where applicable, **individual responses** with reasoning.

You get the kind of feedback you'd expect from a live focus group, without recruiting or scheduling.

***

## Step 1: Get Your Persona IDs and Workspace ID

You'll need 2+ persona IDs and your workspace ID. Listing personas is free (0 credits).

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

  API_KEY = "mvra_live_your_key_here"
  HEADERS = {"Authorization": f"Bearer {API_KEY}"}
  BASE = "https://app.mavera.io/api/v1"

  # List personas
  personas_resp = requests.get(f"{BASE}/personas", headers=HEADERS)
  personas_data = personas_resp.json()
  personas = personas_data["data"]

  # Pick a few; use their IDs in the focus group
  for p in personas[:5]:
      print(f"{p['name']}: {p['id']}")

  # You need a workspace_id — get it from the dashboard or workspaces API
  WORKSPACE_ID = "ws_your_workspace_id"
  ```

  ```javascript JavaScript theme={"dark"}
  const API_KEY = "mvra_live_your_key_here";
  const HEADERS = { Authorization: `Bearer ${API_KEY}` };
  const BASE = "https://app.mavera.io/api/v1";

  const personasRes = await fetch(`${BASE}/personas`, { headers: HEADERS });
  const { data: personas } = await personasRes.json();

  personas.slice(0, 5).forEach((p) => console.log(`${p.name}: ${p.id}`));

  const WORKSPACE_ID = "ws_your_workspace_id";
  ```

  ```bash cURL theme={"dark"}
  # List personas
  curl -s https://app.mavera.io/api/v1/personas \
    -H "Authorization: Bearer mvra_live_your_key_here" | jq '.data[:3] | .[] | {name, id}'
  ```
</CodeGroup>

Replace `ws_your_workspace_id` with the workspace where you want the focus group. Replace the placeholder persona IDs in the next step with real IDs from this list.

***

## Step 2: Create the Focus Group

Send a `POST` with a name, sample size, persona IDs, and questions. Each question has a `type`, `question` text, `order`, and for some types (e.g. `MULTIPLE_CHOICE`) an `options` array.

<CodeGroup>
  ```python Python theme={"dark"}
  focus_group_payload = {
      "name": "Quickstart: Product Launch Feedback",
      "sample_size": 25,
      "persona_ids": [
          "clx1abc2d0001abcdef123456",  # Replace with real IDs from Step 1
          "clx2def3e0002ghijkl789012",
      ],
      "workspace_id": WORKSPACE_ID,
      "questions": [
          {
              "question": "How likely are you to recommend this product to a friend? (0 = not at all, 10 = extremely likely)",
              "type": "NPS",
              "order": 1,
          },
          {
              "question": "The product design feels modern and appealing.",
              "type": "LIKERT",
              "order": 2,
          },
          {
              "question": "Which feature would you use first?",
              "type": "MULTIPLE_CHOICE",
              "options": ["Dashboard", "Reports", "Integrations", "Support"],
              "order": 3,
          },
          {
              "question": "What would make you more likely to purchase?",
              "type": "OPEN_ENDED",
              "order": 4,
          },
      ],
  }

  create_resp = requests.post(
      f"{BASE}/focus-groups",
      headers=HEADERS,
      json=focus_group_payload,
  )
  fg = create_resp.json()

  if "error" in fg:
      raise Exception(fg["error"]["message"])

  focus_group_id = fg["id"]
  status = fg["status"]
  print(f"Focus group created: {focus_group_id}")
  print(f"Status: {status}")
  ```

  ```javascript JavaScript theme={"dark"}
  const focusGroupPayload = {
    name: "Quickstart: Product Launch Feedback",
    sample_size: 25,
    persona_ids: [
      "clx1abc2d0001abcdef123456",
      "clx2def3e0002ghijkl789012",
    ],
    workspace_id: WORKSPACE_ID,
    questions: [
      {
        question: "How likely are you to recommend this product to a friend? (0 = not at all, 10 = extremely likely)",
        type: "NPS",
        order: 1,
      },
      {
        question: "The product design feels modern and appealing.",
        type: "LIKERT",
        order: 2,
      },
      {
        question: "Which feature would you use first?",
        type: "MULTIPLE_CHOICE",
        options: ["Dashboard", "Reports", "Integrations", "Support"],
        order: 3,
      },
      {
        question: "What would make you more likely to purchase?",
        type: "OPEN_ENDED",
        order: 4,
      },
    ],
  };

  const createRes = await fetch(`${BASE}/focus-groups`, {
    method: "POST",
    headers: { ...HEADERS, "Content-Type": "application/json" },
    body: JSON.stringify(focusGroupPayload),
  });
  const fg = await createRes.json();

  if (fg.error) throw new Error(fg.error.message);

  const focusGroupId = fg.id;
  console.log("Focus group created:", focusGroupId);
  console.log("Status:", fg.status);
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://app.mavera.io/api/v1/focus-groups \
    -H "Authorization: Bearer mvra_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Quickstart: Product Launch Feedback",
      "sample_size": 25,
      "persona_ids": ["clx1abc2d0001abcdef123456", "clx2def3e0002ghijkl789012"],
      "workspace_id": "ws_your_workspace_id",
      "questions": [
        {"question": "How likely are you to recommend this product? (0-10)", "type": "NPS", "order": 1},
        {"question": "The product design feels modern.", "type": "LIKERT", "order": 2},
        {"question": "What would make you more likely to purchase?", "type": "OPEN_ENDED", "order": 3}
      ]
    }'
  ```
</CodeGroup>

The response includes `id` and `status`. Status is often `PENDING` or `RUNNING` at first; it moves to `COMPLETED` when all simulated responses are done.

<Tip>
  Start with a small `sample_size` (e.g. 10–25) and 3–5 questions to keep credits and wait time low. You can increase both once you're comfortable with the API.
</Tip>

***

## Step 3: Wait for Completion and Fetch Results

Focus groups run asynchronously. Poll `GET /focus-groups/{id}` until `status` is `COMPLETED`, then read `results`.

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

  def get_focus_group(fg_id):
      r = requests.get(f"{BASE}/focus-groups/{fg_id}", headers=HEADERS)
      return r.json()

  # Poll until completed (with a safety limit)
  for _ in range(60):
      fg = get_focus_group(focus_group_id)
      if "error" in fg:
          raise Exception(fg["error"]["message"])
      if fg.get("status") == "COMPLETED":
          break
      time.sleep(5)
  else:
      raise Exception("Focus group did not complete in time")

  # Inspect results
  for q in fg["results"]:
      print(f"\n--- {q['question']} ({q['type']}) ---")
      print(f"Summary: {q.get('summary', 'N/A')[:200]}...")
      if q.get("type") == "NPS":
          print(f"NPS Score: {q.get('nps_score')}")
          print(f"Promoters: {q.get('promoters')}% | Passives: {q.get('passives')}% | Detractors: {q.get('detractors')}%")
  print(f"\nCredits used: {fg.get('usage', {}).get('credits_used')}")
  ```

  ```javascript JavaScript theme={"dark"}
  async function getFocusGroup(id) {
    const r = await fetch(`${BASE}/focus-groups/${id}`, { headers: HEADERS });
    return r.json();
  }

  let fg;
  for (let i = 0; i < 60; i++) {
    fg = await getFocusGroup(focusGroupId);
    if (fg.error) throw new Error(fg.error.message);
    if (fg.status === "COMPLETED") break;
    await new Promise((r) => setTimeout(r, 5000));
  }
  if (fg.status !== "COMPLETED") throw new Error("Focus group did not complete in time");

  fg.results.forEach((q) => {
    console.log(`\n--- ${q.question} (${q.type}) ---`);
    console.log("Summary:", (q.summary || "N/A").slice(0, 200) + "...");
    if (q.type === "NPS") {
      console.log("NPS Score:", q.nps_score);
      console.log(`Promoters: ${q.promoters}% | Passives: ${q.passives}% | Detractors: ${q.detractors}%`);
    }
  });
  console.log("\nCredits used:", fg.usage?.credits_used);
  ```

  ```bash cURL theme={"dark"}
  # Poll (replace fg_abc123 with your focus group id)
  curl -s "https://app.mavera.io/api/v1/focus-groups/fg_abc123" \
    -H "Authorization: Bearer mvra_live_your_key_here" | jq '{status, results: .results | length, usage}'
  ```
</CodeGroup>

***

## Step 4: Interpret the Results

Each element in `results` corresponds to one question and typically includes:

| Field                    | Description                                                        |
| ------------------------ | ------------------------------------------------------------------ |
| `question`               | The question text.                                                 |
| `type`                   | Question type (NPS, LIKERT, MULTIPLE\_CHOICE, OPEN\_ENDED, etc.).  |
| `summary`                | AI-generated summary of how the segment responded.                 |
| For **NPS**              | `nps_score`, `promoters`, `passives`, `detractors` (percentages).  |
| For **LIKERT**           | Scale distribution or average.                                     |
| For **MULTIPLE\_CHOICE** | Counts or percentages per option.                                  |
| `responses`              | Optional array of individual responses (persona, score/reasoning). |

Example (simplified) for one NPS question:

```json theme={"dark"}
{
  "question_id": "q1",
  "question": "How likely are you to recommend this product?",
  "type": "NPS",
  "nps_score": 42,
  "promoters": 55,
  "passives": 32,
  "detractors": 13,
  "summary": "Strong positive sentiment with Gen Z showing highest likelihood to recommend...",
  "responses": [
    {
      "persona_name": "Gen Z Consumer",
      "score": 9,
      "reasoning": "The product aligns with my values..."
    }
  ]
}
```

Use `summary` for a quick read; use `responses` and segment-level metrics when you need to compare personas or drill into outliers.

***

## Question Types at a Glance

| Type              | Purpose                 | Typical response fields                            |
| ----------------- | ----------------------- | -------------------------------------------------- |
| `NPS`             | Net Promoter Score 0–10 | `nps_score`, `promoters`, `passives`, `detractors` |
| `LIKERT`          | 5-point agreement       | Scale value, distribution                          |
| `MULTIPLE_CHOICE` | Single or multi-select  | Selected option(s), counts                         |
| `OPEN_ENDED`      | Free text               | Summary, individual responses                      |
| `RATING`          | Star rating 1–5         | Rating, explanation                                |
| `YES_NO`          | Binary                  | Yes/No, reasoning                                  |

For the full set (e.g. RANKING, SLIDER, MATRIX, SEMANTIC\_DIFFERENTIAL, CONJOINT, MAXDIFF), see [Focus Groups](/features/focus-groups#question-types).

***

## Credit Costs

| Sample size | Approximate credits |
| ----------- | ------------------- |
| 10–25       | 50–75               |
| 26–50       | 75–125              |
| 51–100      | 125–200             |
| 100+        | 200+                |

Cost also depends on the number and complexity of questions. Check `usage.credits_used` on the completed focus group object.

***

## Common Issues

<AccordionGroup>
  <Accordion title="Invalid workspace_id or 403">
    Ensure the workspace exists and your API key has access. Get the ID from the dashboard or workspaces API.
  </Accordion>

  <Accordion title="Invalid persona_id">
    Use IDs from `GET /personas`. You need at least one persona; two or more give more useful segment variation.
  </Accordion>

  <Accordion title="MULTIPLE_CHOICE missing options">
    For `type: "MULTIPLE_CHOICE"` you must include an `options` array of strings.
  </Accordion>

  <Accordion title="Focus group stuck in PENDING/RUNNING">
    Large sample sizes or many questions take longer. Poll for up to 5–10 minutes; if it never completes, check [status](https://status.mavera.io) or contact support.
  </Accordion>

  <Accordion title="402 credits_exhausted">
    Refill credits or reduce sample size / question count. See [Credits](/guides/credits).
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Run First Focus Group" icon="book" href="/tutorials/run-first-focus-group">
    Full tutorial with Python/JS scripts
  </Card>

  <Card title="Focus Groups" icon="users" href="/features/focus-groups">
    All 12 question types, best practices
  </Card>

  <Card title="Persona Selection" icon="user" href="/cookbooks/persona-selection">
    Choose personas by use case
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/focus-groups/create-a-focus-group">
    Full request/response specification
  </Card>
</CardGroup>

Once you're comfortable with one run, try varying personas and question mixes to simulate different segments (e.g. B2B vs consumer) or add more quantitative vs qualitative questions.
