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

# Content Localization via Personas

> Generate the same content piece with different regional personas applied — each persona's cultural context influences tone, idioms, and messaging for culturally-adapted content variants

## Scenario

You have one core message — a product announcement, a campaign brief, or a landing page — and you need it to resonate in 4–6 different markets. Direct translation loses nuance. A U.S.-centric blog post doesn't land the same way in Germany, Japan, or Brazil.

This playbook uses Mavera personas as cultural lenses. You generate the same content multiple times, each with a different regional persona applied. The persona doesn't just translate — it adapts idioms, adjusts formality, reframes value propositions, and shifts cultural references so the output feels native to each market.

<Info>
  **Mavera-only.** No translation API, no localization platform. Personas carry the cultural context; Generate produces the adapted content.
</Info>

***

## Architecture

```mermaid theme={"dark"}
flowchart LR
    A["Core Brief"] --> B1["US Consumer"] --> C1["US Version"]
    A --> B2["UK Professional"] --> C2["UK Version"]
    A --> B3["DACH B2B Buyer"] --> C3["DACH Version"]
    A --> B4["Japan Enterprise"] --> C4["Japan Version"]
    A --> B5["Brazil Millennial"] --> C5["Brazil Version"]
    A --> B6["India Startup"] --> C6["India Version"]
```

***

## What You Need

| Requirement                        | Details                                                                                                             |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Mavera API key**                 | Starts with `mvra_live_`. Get one at [Developer Settings](https://app.mavera.io/settings/developer).                |
| **Workspace ID**                   | From your dashboard URL (`ws_...`).                                                                                 |
| **Regional persona IDs**           | Pre-built or custom personas representing each target market. Use `GET /personas` to browse, or create custom ones. |
| **Core content brief**             | The message, product, and key points you want adapted.                                                              |
| **Brand voice ID** (optional)      | Apply a consistent brand voice across all regional variants.                                                        |
| **Credits**                        | \~200–600 depending on region count and content type. See [Credits Estimate](#credits-estimate).                    |
| **Python 3.8+** or **Node.js 18+** | `requests` for Python; native `fetch` for Node.                                                                     |

```
MAVERA_API_KEY=mvra_live_your_key_here
MAVERA_WORKSPACE_ID=ws_your_workspace_id
BRAND_VOICE_ID=bv_optional_voice_id
```

***

## The Flow

<Steps>
  <Step title="Define regional personas">
    List the markets you want to target. Use pre-built personas or create custom ones with `POST /personas` using the `NORTH_STAR` or `ADVANCED` pipeline. Each persona encodes cultural context, communication preferences, and decision-making patterns.
  </Step>

  <Step title="Prepare the core brief">
    Write your content brief once — topic, key points, target audience description, and desired format. This brief stays constant across all regions.
  </Step>

  <Step title="Generate with each persona">
    For each region, call `POST /generations` with the same `app_id`, `input_data`, and `brand_voice_id` — but inject the regional persona context into the input. The persona influences the AI's cultural framing.
  </Step>

  <Step title="Compare and review">
    Collect all variants. Compare tone, idioms, formality level, and value proposition framing across regions.
  </Step>
</Steps>

***

## Stage 1 — Create Regional Personas

If you already have persona IDs for your target regions, skip to Stage 2. Otherwise, create custom personas for each market.

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

  API_KEY = os.environ["MAVERA_API_KEY"]
  WORKSPACE_ID = os.environ["MAVERA_WORKSPACE_ID"]
  BRAND_VOICE_ID = os.environ.get("BRAND_VOICE_ID")
  BASE = "https://app.mavera.io/api/v1"
  HEADERS = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  REGIONS = [
      {
          "name": "US Tech-Savvy Consumer",
          "description": "American millennial, early adopter, values convenience and ROI. "
                         "Casual communication style, appreciates humor and directness.",
          "region": "US",
      },
      {
          "name": "UK B2B Decision Maker",
          "description": "British senior manager at a mid-size company. Values understatement, "
                         "evidence-based claims, and dry wit. Prefers formal-but-not-stiff tone.",
          "region": "UK",
      },
      {
          "name": "DACH Enterprise Buyer",
          "description": "German-speaking procurement lead. Values precision, data, certifications, "
                         "and thoroughness. Direct communication, low tolerance for hype.",
          "region": "DACH",
      },
      {
          "name": "Japan Enterprise IT",
          "description": "Japanese IT director at a large corporation. Values harmony, consensus, "
                         "and long-term reliability. Formal tone, indirect communication style.",
          "region": "Japan",
      },
      {
          "name": "Brazil Digital-First Millennial",
          "description": "Brazilian young professional, digitally native, values community and "
                         "personal connection. Warm, enthusiastic tone with storytelling.",
          "region": "Brazil",
      },
      {
          "name": "India Startup Founder",
          "description": "Indian tech founder scaling a startup. Values rapid results, cost "
                         "efficiency, and global ambition. Mix of formal and energetic tone.",
          "region": "India",
      },
  ]

  persona_ids = {}

  for region in REGIONS:
      resp = requests.post(
          f"{BASE}/personas",
          headers=HEADERS,
          json={
              "pipeline_type": "NORTH_STAR",
              "name": region["name"],
              "description": region["description"],
              "workspace_id": WORKSPACE_ID,
          },
      )
      resp.raise_for_status()
      persona = resp.json()
      persona_ids[region["region"]] = persona["id"]
      print(f"  {region['region']}: {persona['id']} ({persona['name']})")

  print(f"\nCreated {len(persona_ids)} regional personas")
  ```

  ```javascript JavaScript theme={"dark"}
  const API_KEY = process.env.MAVERA_API_KEY;
  const WORKSPACE_ID = process.env.MAVERA_WORKSPACE_ID;
  const BRAND_VOICE_ID = process.env.BRAND_VOICE_ID || null;
  const BASE = "https://app.mavera.io/api/v1";
  const HEADERS = {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  };

  const REGIONS = [
    {
      name: "US Tech-Savvy Consumer",
      description:
        "American millennial, early adopter, values convenience and ROI. " +
        "Casual communication style, appreciates humor and directness.",
      region: "US",
    },
    {
      name: "UK B2B Decision Maker",
      description:
        "British senior manager at a mid-size company. Values understatement, " +
        "evidence-based claims, and dry wit. Prefers formal-but-not-stiff tone.",
      region: "UK",
    },
    {
      name: "DACH Enterprise Buyer",
      description:
        "German-speaking procurement lead. Values precision, data, certifications, " +
        "and thoroughness. Direct communication, low tolerance for hype.",
      region: "DACH",
    },
    {
      name: "Japan Enterprise IT",
      description:
        "Japanese IT director at a large corporation. Values harmony, consensus, " +
        "and long-term reliability. Formal tone, indirect communication style.",
      region: "Japan",
    },
    {
      name: "Brazil Digital-First Millennial",
      description:
        "Brazilian young professional, digitally native, values community and " +
        "personal connection. Warm, enthusiastic tone with storytelling.",
      region: "Brazil",
    },
    {
      name: "India Startup Founder",
      description:
        "Indian tech founder scaling a startup. Values rapid results, cost " +
        "efficiency, and global ambition. Mix of formal and energetic tone.",
      region: "India",
    },
  ];

  const personaIds = {};

  for (const region of REGIONS) {
    const resp = await fetch(`${BASE}/personas`, {
      method: "POST",
      headers: HEADERS,
      body: JSON.stringify({
        pipeline_type: "NORTH_STAR",
        name: region.name,
        description: region.description,
        workspace_id: WORKSPACE_ID,
      }),
    });
    const persona = await resp.json();
    personaIds[region.region] = persona.id;
    console.log(`  ${region.region}: ${persona.id} (${persona.name})`);
  }

  console.log(`\nCreated ${Object.keys(personaIds).length} regional personas`);
  ```
</CodeGroup>

<Warning>
  Custom persona creation costs **300 credits each**. If you're localizing regularly, create personas once and reuse their IDs. Store them in your config or database.
</Warning>

***

## Stage 2 — Define the Core Brief

The brief is the same for every region. The persona changes the cultural lens, not the facts.

<CodeGroup>
  ```python Python theme={"dark"}
  CORE_BRIEF = {
      "app_id": "blog_post_generator",
      "input_data": {
          "topic": "Introducing Workflow Automation for Growing Teams",
          "target_audience": "Operations leaders at 50-500 person companies",
          "length": "800 words",
          "key_points": [
              "Manual processes cost teams 15+ hours per week",
              "Our automation builder requires zero coding",
              "200+ integrations with tools you already use",
              "Customers see 60% time savings in the first month",
          ],
      },
  }
  ```

  ```javascript JavaScript theme={"dark"}
  const CORE_BRIEF = {
    app_id: "blog_post_generator",
    input_data: {
      topic: "Introducing Workflow Automation for Growing Teams",
      target_audience: "Operations leaders at 50-500 person companies",
      length: "800 words",
      key_points: [
        "Manual processes cost teams 15+ hours per week",
        "Our automation builder requires zero coding",
        "200+ integrations with tools you already use",
        "Customers see 60% time savings in the first month",
      ],
    },
  };
  ```
</CodeGroup>

***

## Stage 3 — Generate Regional Variants

For each persona, inject the cultural context into the generation call. The persona ID tells the Chat layer how to frame the content; the brief provides the facts.

<CodeGroup>
  ```python Python theme={"dark"}
  from openai import OpenAI

  mavera = OpenAI(
      api_key=API_KEY,
      base_url=BASE,
  )


  def generate_localized(region_name, persona_id, brief, brand_voice_id=None):
      """Generate content adapted for a specific regional persona."""
      localized_input = {
          **brief["input_data"],
          "target_audience": f"{brief['input_data']['target_audience']} — "
                             f"adapted for {region_name} market cultural context",
      }

      payload = {
          "app_id": brief["app_id"],
          "title": f"Localized — {region_name}",
          "input_data": localized_input,
          "workspace_id": WORKSPACE_ID,
      }
      if brand_voice_id:
          payload["brand_voice_id"] = brand_voice_id

      resp = requests.post(f"{BASE}/generations", headers=HEADERS, json=payload)
      resp.raise_for_status()
      gen = resp.json()

      if gen.get("status") in ("PENDING", "RUNNING"):
          gen = wait_for_generation(gen["id"])

      return gen


  def wait_for_generation(gen_id, max_wait=300):
      for _ in range(max_wait // 10):
          resp = requests.get(f"{BASE}/generations/{gen_id}", headers=HEADERS)
          data = resp.json()
          if data.get("status") == "COMPLETED":
              return data
          time.sleep(10)
      raise TimeoutError(f"Generation {gen_id} timed out")


  # Also score each variant with the persona for cultural fit
  def score_cultural_fit(content, persona_id, region_name):
      """Use Chat with the regional persona to score cultural appropriateness."""
      resp = mavera.responses.create(
          model="mavera-1",
          input=[
              {
                  "role": "user",
                  "content": (
                      f"You are evaluating content for the {region_name} market. "
                      "Score cultural fit 1-10. Flag any idioms, references, or tone "
                      "choices that feel foreign or off-putting. Be specific.\n\n"
                      f"---\n{content[:3000]}\n---"
                  ),
              },
          ],
          extra_body={"persona_id": persona_id},
      )
      return resp.output[0].content[0].text


  variants = {}
  total_credits = 0

  for region, pid in persona_ids.items():
      print(f"\nGenerating for {region}...")
      gen = generate_localized(region, pid, CORE_BRIEF, BRAND_VOICE_ID)
      credits = gen.get("usage", {}).get("credits_used", 0)
      total_credits += credits

      fit_score = score_cultural_fit(gen.get("output", ""), pid, region)

      variants[region] = {
          "output": gen.get("output", ""),
          "credits": credits,
          "cultural_fit": fit_score,
      }
      print(f"  ✓ {credits} credits | {len(gen.get('output', ''))} chars")
      print(f"  Cultural fit: {fit_score[:200]}...")

  print(f"\n{'='*50}")
  print(f"Generated {len(variants)} regional variants | {total_credits} total credits")
  ```

  ```javascript JavaScript theme={"dark"}
  import OpenAI from "openai";

  const mavera = new OpenAI({
    apiKey: API_KEY,
    baseURL: BASE,
  });

  async function generateLocalized(regionName, personaId, brief, brandVoiceId) {
    const localizedInput = {
      ...brief.input_data,
      target_audience: `${brief.input_data.target_audience} — adapted for ${regionName} market cultural context`,
    };

    const payload = {
      app_id: brief.app_id,
      title: `Localized — ${regionName}`,
      input_data: localizedInput,
      workspace_id: WORKSPACE_ID,
    };
    if (brandVoiceId) payload.brand_voice_id = brandVoiceId;

    const resp = await fetch(`${BASE}/generations`, {
      method: "POST",
      headers: HEADERS,
      body: JSON.stringify(payload),
    });
    let gen = await resp.json();

    if (gen.status === "PENDING" || gen.status === "RUNNING") {
      gen = await waitForGeneration(gen.id);
    }
    return gen;
  }

  async function waitForGeneration(genId, maxWait = 300) {
    for (let elapsed = 0; elapsed < maxWait; elapsed += 10) {
      const resp = await fetch(`${BASE}/generations/${genId}`, { headers: HEADERS });
      const data = await resp.json();
      if (data.status === "COMPLETED") return data;
      await new Promise((r) => setTimeout(r, 10000));
    }
    throw new Error(`Generation ${genId} timed out`);
  }

  async function scoreCulturalFit(content, personaId, regionName) {
    const resp = await mavera.responses.create({
      model: "mavera-1",
      input: [
        {
          role: "user",
          content:
            `You are evaluating content for the ${regionName} market. ` +
            "Score cultural fit 1-10. Flag any idioms or tone choices that feel foreign.\n\n" +
            `---\n${content.slice(0, 3000)}\n---`,
        },
      ],
      persona_id: personaId,
    });
    return resp.output[0].content[0].text;
  }

  const variants = {};
  let totalCredits = 0;

  for (const [region, pid] of Object.entries(personaIds)) {
    console.log(`\nGenerating for ${region}...`);
    const gen = await generateLocalized(region, pid, CORE_BRIEF, BRAND_VOICE_ID);
    const credits = gen.usage?.credits_used || 0;
    totalCredits += credits;

    const fitScore = await scoreCulturalFit(gen.output || "", pid, region);

    variants[region] = {
      output: gen.output || "",
      credits,
      cultural_fit: fitScore,
    };
    console.log(`  ✓ ${credits} credits | ${(gen.output || "").length} chars`);
    console.log(`  Cultural fit: ${fitScore.slice(0, 200)}...`);
  }

  console.log(`\nGenerated ${Object.keys(variants).length} regional variants | ${totalCredits} total credits`);
  ```
</CodeGroup>

***

## Example Output Differences

The same "60% time savings" claim lands differently across regions:

| Region     | Adapted Framing                                                                                                    |
| ---------- | ------------------------------------------------------------------------------------------------------------------ |
| **US**     | "Save 15 hours a week. That's a whole Tuesday back."                                                               |
| **UK**     | "Our customers typically recover 60% of time previously spent on manual tasks."                                    |
| **DACH**   | "Measured across 200+ implementations: average process time reduction of 60.3%."                                   |
| **Japan**  | "Many teams have reported that after careful implementation, their workflows became significantly more efficient." |
| **Brazil** | "Imagine having an extra day each week to focus on what really matters to your team."                              |
| **India**  | "At this price point, the 60% efficiency gain delivers ROI within the first billing cycle."                        |

***

## Variations

<AccordionGroup>
  <Accordion title="Multiple content types per region">
    Run the same persona across multiple generation apps — blog, email, social — for a full regional content kit:

    ```python theme={"dark"}
    APPS = ["blog_post_generator", "email_sequence_generator", "social_post_generator"]
    for region, pid in persona_ids.items():
        for app_id in APPS:
            brief = {**CORE_BRIEF, "app_id": app_id}
            gen = generate_localized(region, pid, brief, BRAND_VOICE_ID)
    ```
  </Accordion>

  <Accordion title="Focus Group validation per region">
    After generating, run a Focus Group with the same regional persona to validate the content resonates:

    ```python theme={"dark"}
    fg_resp = requests.post(f"{BASE}/focus-groups", headers=HEADERS, json={
        "name": f"Localization Check — {region}",
        "sample_size": 15,
        "persona_ids": [persona_id],
        "workspace_id": WORKSPACE_ID,
        "questions": [
            {"question": "How well does this content resonate with your cultural context? (1-10)", "type": "SCALE", "order": 1},
            {"question": "What feels foreign or off-putting?", "type": "OPEN_ENDED", "order": 2},
        ],
    })
    ```
  </Accordion>

  <Accordion title="Language-specific generation">
    Add a language instruction to the input data for non-English markets:

    ```python theme={"dark"}
    localized_input["language"] = "German"
    localized_input["language_note"] = "Write in German. Use formal Sie address."
    ```
  </Accordion>

  <Accordion title="A/B within a region">
    Generate two variants per region — one conservative, one bold — and let the Focus Group pick:

    ```python theme={"dark"}
    for tone in ["conservative and formal", "bold and conversational"]:
        brief_variant = {**CORE_BRIEF}
        brief_variant["input_data"]["tone"] = tone
        gen = generate_localized(f"{region} ({tone})", pid, brief_variant)
    ```
  </Accordion>

  <Accordion title="Pre-built persona shortcut">
    Skip custom persona creation by using Mavera's pre-built generational and professional personas (`GET /personas`), then adding regional context in the generation prompt.
  </Accordion>
</AccordionGroup>

***

## Credits Estimate

| Operation                                | Typical Cost              | Notes                               |
| ---------------------------------------- | ------------------------- | ----------------------------------- |
| Custom persona creation (×6)             | 1,800 credits             | 300 each; one-time cost — reuse IDs |
| Generation per region                    | 15–30 credits             | Depends on content length           |
| Cultural fit scoring per region          | 1–5 credits               | Chat call with persona              |
| **Total (6 regions, new personas)**      | **\~1,900–2,010 credits** | First run with persona creation     |
| **Total (6 regions, existing personas)** | **\~96–210 credits**      | Subsequent runs                     |

<Tip>
  Create personas once and store the IDs. After the initial persona investment, localization runs cost only \~100–200 credits per content piece across 6 regions.
</Tip>

***

## What's Next

<CardGroup cols={2}>
  <Card title="Content Series Generation" icon="layer-group" href="/playbooks/content-series-generation">
    Extend each regional variant into a multi-part series
  </Card>

  <Card title="A/B Copy Production" icon="clone" href="/playbooks/ab-copy-production">
    Test different voices within the same region
  </Card>

  <Card title="Message Testing Matrix" icon="table-cells" href="/playbooks/message-testing-matrix">
    5 messages × 5 personas — quantitative message fit
  </Card>

  <Card title="Personas" icon="users" href="/features/personas">
    Pre-built and custom persona reference
  </Card>

  <Card title="Content Generation" icon="wand-magic-sparkles" href="/features/content-generation">
    Full API reference for generation apps
  </Card>

  <Card title="Credits & Budget" icon="coins" href="/cookbooks/credits-budget-alerts">
    Track and manage credit usage
  </Card>
</CardGroup>
