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

# TrustScore Monitoring → Reputation Response

> Detect TrustScore drops, analyze root causes with Mave Agent, and generate response templates

## Scenario

Your TrustScore dropped from 4.5 to 4.2 this month. Why? You pull recent negative reviews, send them to Mave for root cause analysis, then generate response strategies and specific reply drafts. This creates a rapid-response loop: detect score drops → understand causes → respond systematically.

**Flow:** Trustpilot `GET /business-units/{id}` (score) → Compare to baseline → If dropped: `GET /reviews` (recent 1-3 star) → Mavera `POST /mave/chat` (root cause) → `POST /generations` (response drafts)

## Architecture

```mermaid theme={"dark"}
flowchart LR
    A["Trustpilot GET /business-units/{id}"] --> B["Compare to baseline"]
    B --> C["GET /reviews (1-3 stars)"]
    C --> D["POST /api/v1/mave/chat"]
    D --> E["POST /api/v1/generations"]
    E --> F["Root cause report + templates"]
```

## Code

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

  TP_KEY = os.environ["TRUSTPILOT_API_KEY"]
  MV = os.environ["MAVERA_API_KEY"]
  BU_ID = os.environ["TRUSTPILOT_BU_ID"]
  TP_BASE = "https://api.trustpilot.com/v1"
  MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

  # 1. Current TrustScore
  bu = requests.get(f"{TP_BASE}/business-units/{BU_ID}",
      params={"apikey": TP_KEY}).json()
  current_score = bu.get("score", {}).get("trustScore", 0)
  review_count = bu.get("numberOfReviews", {}).get("total", 0)
  star_dist = bu.get("score", {}).get("stars", {})

  BASELINE_SCORE = 4.5

  print(f"Current TrustScore: {current_score} (baseline: {BASELINE_SCORE})")
  print(f"Total reviews: {review_count}")
  print(f"Star distribution: {star_dist}")

  # 2. If score dropped, pull recent negative reviews
  if current_score < BASELINE_SCORE:
      drop = BASELINE_SCORE - current_score
      print(f"\n⚠ Score dropped by {drop:.1f} points")

      negative_reviews = []
      for stars in [1, 2, 3]:
          r = requests.get(f"{TP_BASE}/business-units/{BU_ID}/reviews",
              params={"apikey": TP_KEY, "stars": stars, "perPage": 20,
                       "orderBy": "createdat.desc"})
          r.raise_for_status()
          negative_reviews.extend(r.json().get("reviews", []))
          time.sleep(0.2)

      # 3. Build review block for analysis
      review_block = "\n\n".join(
          f"[{r.get('stars',0)}★] {r.get('title','No title')}\n{r.get('text','')[:300]}\nDate: {r.get('createdAt','')[:10]}"
          for r in negative_reviews[:20]
      )

      # 4. Mave root cause analysis
      analysis = requests.post("https://app.mavera.io/api/v1/mave/chat",
          headers=MV_H,
          json={"message": f"""Our Trustpilot TrustScore dropped from {BASELINE_SCORE} to {current_score}.
  Total reviews: {review_count}. Star distribution: {star_dist}.

  Recent negative reviews:
  {review_block}

  Analyze:
  1. Root causes — what themes drive negative reviews?
  2. Frequency — which issues appear most?
  3. Severity — which issues cause 1-star vs 3-star?
  4. Trend — are issues getting worse or improving?
  5. Actionable fixes — what operational changes would address each root cause?
  6. Response strategy — how to reply to each theme category"""}).json()

      print("\n=== Root Cause Analysis ===")
      print(analysis.get("content", "")[:1500])

      # 5. Generate response templates
      gen = requests.post("https://app.mavera.io/api/v1/generations",
          headers=MV_H,
          json={"prompt": f"""Based on this root cause analysis, generate 4 review response templates:

  {analysis.get('content','')[:1000]}

  For each template:
  - Category name (e.g., "Shipping Delay", "Product Quality")
  - Tone: empathetic, solution-oriented, professional
  - Acknowledge the specific issue
  - Offer a concrete next step
  - Keep under 100 words each
  - Never use corporate jargon"""}).json()

      print("\n=== Response Templates ===")
      print(gen.get("output", gen.get("content", gen.get("text", "")))[:1200])

  else:
      print(f"✓ Score stable at {current_score}")
  ```

  ```javascript JavaScript theme={"dark"}
  const TP_KEY = process.env.TRUSTPILOT_API_KEY;
  const MV = process.env.MAVERA_API_KEY;
  const BU_ID = process.env.TRUSTPILOT_BU_ID;
  const TP_BASE = "https://api.trustpilot.com/v1";
  const MV_H = { Authorization: `Bearer ${MV}`, "Content-Type": "application/json" };

  // 1. TrustScore
  const bu = await fetch(`${TP_BASE}/business-units/${BU_ID}?apikey=${TP_KEY}`).then((r) => r.json());
  const currentScore = bu.score?.trustScore || 0;
  const reviewCount = bu.numberOfReviews?.total || 0;
  const starDist = bu.score?.stars || {};
  const BASELINE = 4.5;

  console.log(`TrustScore: ${currentScore} (baseline: ${BASELINE})`);

  // 2. If dropped
  if (currentScore < BASELINE) {
    console.log(`Score dropped ${(BASELINE - currentScore).toFixed(1)} pts`);

    const negReviews = [];
    for (const stars of [1, 2, 3]) {
      const res = await fetch(
        `${TP_BASE}/business-units/${BU_ID}/reviews?apikey=${TP_KEY}&stars=${stars}&perPage=20&orderBy=createdat.desc`
      );
      negReviews.push(...((await res.json()).reviews || []));
      await new Promise((r) => setTimeout(r, 200));
    }

    const reviewBlock = negReviews.slice(0, 20)
      .map((r) => `[${r.stars}★] ${r.title || "No title"}\n${(r.text || "").slice(0, 300)}`)
      .join("\n\n");

    // 3. Root cause
    const analysis = await fetch("https://app.mavera.io/api/v1/mave/chat", {
      method: "POST", headers: MV_H,
      body: JSON.stringify({
        message: `TrustScore dropped ${BASELINE}→${currentScore}. Reviews: ${reviewCount}.\n\n${reviewBlock}\n\nAnalyze: 1) Root causes 2) Frequency 3) Severity 4) Trend 5) Fixes 6) Response strategy`,
      }),
    }).then((r) => r.json());

    console.log("\n=== Root Cause ===");
    console.log((analysis.content || "").slice(0, 1500));

    // 4. Response templates
    const gen = await fetch("https://app.mavera.io/api/v1/generations", {
      method: "POST", headers: MV_H,
      body: JSON.stringify({
        prompt: `Generate 4 review response templates based on:\n\n${(analysis.content || "").slice(0, 1000)}\n\nEmpathetic, solution-oriented, under 100 words each.`,
      }),
    }).then((r) => r.json());

    console.log("\n=== Templates ===");
    console.log(gen.output || gen.content || gen.text || "");
  }
  ```
</CodeGroup>

## Example Output

```text theme={"dark"}
TrustScore: 4.2 (baseline: 4.5)
⚠ Score dropped by 0.3 points

=== Root Cause Analysis ===

## Theme Analysis (20 recent negative reviews)

| Theme | Mentions | Avg Stars | Trend |
|-------|----------|-----------|-------|
| Shipping delays | 8 | 1.8 | Worsening (5 in last 2 weeks) |
| Product quality | 5 | 2.4 | Stable |
| Customer support wait | 4 | 2.0 | New issue (all from last month) |
| Billing errors | 3 | 1.3 | Stable |

## Root Cause: Shipping
Carrier switch in March caused 3-5 day delays. Reviews mention "used to arrive in 2 days."

## Actionable Fixes
1. Shipping: Revert to previous carrier or add expedited option
2. Support: Hire 2 additional agents — wait times exceeded 45 min
3. Billing: Audit subscription renewal flow — 3 cases of double-charge

=== Response Templates ===

### Shipping Delay
"Hi [Name], I'm sorry your order took longer than expected. We recently
changed carriers and are actively fixing the delays. I've escalated your
order — you'll receive tracking within 24 hours. If it doesn't arrive by
[date], reply here and I'll personally ensure a full refund."

### Customer Support Wait
"Thank you for your patience, [Name]. Wait times have been longer than our
standard, and we take that seriously. We've added staff this week. I'd love
to resolve your issue now — can you DM us your case number?"
```

## Error Handling

<AccordionGroup>
  <Accordion title="TrustScore precision">TrustScore is rounded to 1 decimal. A 0.1 change can represent dozens of reviews. Track review volume alongside score for context.</Accordion>
  <Accordion title="Baseline storage">Store your baseline TrustScore in a database or config file. The code uses a hardcoded baseline — replace with dynamic comparison in production.</Accordion>
  <Accordion title="Response posting requires OAuth">Reading reviews uses the API key. Posting replies requires OAuth 2.0 (`POST /reviews/{id}/reply`). Set up OAuth before automating responses.</Accordion>
</AccordionGroup>
