Skip to main content

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.

Scenario

You’re opening a new location or launching a competitive product. Before investing, you need to understand the local competitive landscape — who’s already there, how they’re rated, what they offer, and where the gaps are. You use Yelp’s business search to map competitors by category and location, then send the landscape data to Mave for strategic analysis. Flow: Yelp GET /businesses/search (category + location) → Aggregate: ratings, review counts, price ranges, categories → Mavera POST /mave/chat → Competitive landscape report

Architecture

Code

import os, requests, time
from collections import defaultdict

YELP = os.environ["YELP_API_KEY"]
MV = os.environ["MAVERA_API_KEY"]
YELP_BASE = "https://api.yelp.com/v3"
YELP_H = {"Authorization": f"Bearer {YELP}"}
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

# 1. Search businesses by category and location
CATEGORY = "coffee"
LOCATION = "Austin, TX"

businesses = []
for offset in range(0, 200, 50):
    r = requests.get(f"{YELP_BASE}/businesses/search",
        headers=YELP_H,
        params={
            "term": CATEGORY,
            "location": LOCATION,
            "limit": 50,
            "offset": offset,
            "sort_by": "review_count",
        })
    if r.status_code == 429:
        time.sleep(2)
        continue
    r.raise_for_status()
    batch = r.json().get("businesses", [])
    if not batch:
        break
    businesses.extend(batch)
    time.sleep(0.5)

print(f"Found {len(businesses)} {CATEGORY} businesses in {LOCATION}")

# 2. Aggregate market data
price_tiers = defaultdict(list)
categories_seen = defaultdict(int)
neighborhoods = defaultdict(int)

for biz in businesses:
    price = biz.get("price", "N/A")
    rating = biz.get("rating", 0)
    reviews = biz.get("review_count", 0)
    price_tiers[price].append({"rating": rating, "reviews": reviews, "name": biz["name"]})

    for cat in biz.get("categories", []):
        categories_seen[cat.get("alias", "")] += 1

    loc = biz.get("location", {})
    hood = loc.get("city", LOCATION)
    neighborhoods[hood] += 1

# 3. Build analysis context
market_summary = []
for price, bizes in sorted(price_tiers.items()):
    avg_rating = sum(b["rating"] for b in bizes) / len(bizes)
    avg_reviews = sum(b["reviews"] for b in bizes) / len(bizes)
    top = sorted(bizes, key=lambda x: -x["reviews"])[:3]
    top_names = ", ".join(b["name"] for b in top)
    market_summary.append(
        f"- {price} tier: {len(bizes)} businesses, avg {avg_rating:.1f}/5, "
        f"avg {avg_reviews:.0f} reviews. Leaders: {top_names}"
    )

cat_summary = ", ".join(f"{k} ({v})" for k, v in
    sorted(categories_seen.items(), key=lambda x: -x[1])[:10])

biz_block = "\n".join(
    f"- {b['name']}: {b.get('rating',0)}/5, {b.get('review_count',0)} reviews, "
    f"Price: {b.get('price','N/A')}, Categories: {', '.join(c.get('title','') for c in b.get('categories',[]))}"
    for b in sorted(businesses, key=lambda x: -x.get("review_count", 0))[:15]
)

# 4. Mave competitive analysis
analysis = requests.post("https://app.mavera.io/api/v1/mave/chat",
    headers=MV_H,
    json={"message": f"""Analyze the competitive landscape for "{CATEGORY}" in {LOCATION}.

MARKET OVERVIEW:
{len(businesses)} businesses found

BY PRICE TIER:
{chr(10).join(market_summary)}

CATEGORY OVERLAP:
{cat_summary}

TOP 15 BY REVIEW VOLUME:
{biz_block}

Produce:
1. Market saturation assessment (oversaturated / balanced / underserved)
2. Competitive clusters (which businesses compete directly)
3. White space opportunities (underserved niches, price gaps, location gaps)
4. Positioning recommendations for a new entrant
5. Differentiator suggestions based on what existing players lack
6. Pricing strategy recommendation"""}).json()

print(f"\n=== {CATEGORY.title()} Market in {LOCATION} ===")
print(analysis.get("content", "")[:2000])

Example Output

=== Coffee Market in Austin, TX ===

## Market Saturation: BALANCED with NICHE GAPS

183 coffee businesses. Downtown oversaturated (42 within 1 mile).
East Austin and South Congress underserved relative to foot traffic.

## Competitive Clusters
- **Specialty/Third Wave** (28 businesses): Houndstooth, Fleet, Merit.
  Avg 4.5/5, $$ pricing. Competing on quality and ambiance.
- **Chain/Drive-thru** (34): Starbucks, Dutch Bros. Avg 3.8/5, $.
  Competing on speed and consistency.
- **Café + Food** (45): Cenote, Epoch. Avg 4.3/5, $$.
  Competing on experience and dwell time.

## White Space Opportunities
1. **Specialty + drive-thru** — no Austin player combines third-wave
   quality with drive-thru convenience. Nearest: Dutch Bros (not specialty).
2. **East Austin specialty** — 3 specialty shops vs 12 downtown.
   Growing residential density with no quality option.
3. **Evening coffee** — 80% close by 6pm. Night-market concept untested.

## Positioning Recommendation
Enter the $$ specialty tier in East Austin with drive-thru capability.
Differentiate on: speed (under 3 min), local roasting, and evening hours.

Error Handling

Yelp limits search results to 1,000 total (offset + limit ≤ 1000). For dense markets, narrow by neighborhood or category.
The free tier allows only 5,000 total API calls. Business search is the most expensive — each call counts as 1. Cache results aggressively.
Not all businesses have price set. The code groups these as "N/A". Filter or exclude for cleaner tier analysis.