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

BigCommerce stores custom customer attributes — company type, purchase frequency, preferred categories — via customer attributes. You pull these, group customers into segments by shared attribute values, and create Mavera personas from each real-world segment so generated content reflects actual buyer profiles. Flow: BigCommerce GET /v3/customers?include=attributes → Group by attribute values → Mavera POST /api/v1/personas per segment

Architecture

Code

import os, requests, time
from collections import defaultdict

STORE = os.environ["BIGCOMMERCE_STORE_HASH"]
BC_TOKEN = os.environ["BIGCOMMERCE_ACCESS_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
BC = f"https://api.bigcommerce.com/stores/{STORE}/v3"
BC_HEADERS = {"X-Auth-Token": BC_TOKEN, "Content-Type": "application/json", "Accept": "application/json"}
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

customers, page = [], 1
while True:
    r = requests.get(f"{BC}/customers",
        headers=BC_HEADERS,
        params={"include": "attributes", "page": page, "limit": 50})
    if r.status_code == 429:
        time.sleep(2); continue
    r.raise_for_status()
    batch = r.json().get("data", [])
    customers.extend(batch)
    if len(batch) < 50: break
    page += 1
    time.sleep(0.2)

SEGMENT_ATTR = "customer_type"
segments = defaultdict(list)
for cust in customers:
    for attr in cust.get("attributes", []):
        if attr.get("attribute_name") == SEGMENT_ATTR and attr.get("attribute_value"):
            segments[attr["attribute_value"]].append(cust)
            break

personas = []
for seg_name, members in segments.items():
    if len(members) < 3:
        continue
    companies = list({c.get("company", "") for c in members if c.get("company")})[:5]
    emails = [c.get("email", "") for c in members]
    domains = list({e.split("@")[-1] for e in emails if "@" in e and not any(
        d in e for d in ["gmail", "yahoo", "hotmail", "outlook"])})[:5]

    spend_attr = next((a["attribute_value"] for m in members
        for a in m.get("attributes", [])
        if a.get("attribute_name") == "avg_order_value"), "unknown")

    r = requests.post("https://app.mavera.io/api/v1/personas", headers=MH, json={
        "name": f"BigCommerce: {seg_name}",
        "description": (f"{seg_name} segment from BigCommerce. "
            f"N={len(members)}. Companies: {', '.join(companies[:3])}. "
            f"Domains: {', '.join(domains[:3])}. Avg order value: {spend_attr}."),
        "demographic": {"companies": companies, "segment_size": len(members)},
        "psychographic": {"buyer_type": seg_name.lower()},
    })
    r.raise_for_status()
    persona = r.json()
    personas.append({"segment": seg_name, "id": persona["id"], "n": len(members)})
    print(f"{seg_name}: {persona['id']} ({len(members)} customers)")
    time.sleep(0.3)

print(f"\nCreated {len(personas)} personas from {len(customers)} customers")

Example Output

[
  { "segment": "Enterprise", "id": "per_ent_8k2m", "n": 45 },
  { "segment": "SMB", "id": "per_smb_3f9a", "n": 120 },
  { "segment": "Wholesale", "id": "per_ws_7b4c", "n": 28 },
  { "segment": "Marketplace Seller", "id": "per_mps_1d6e", "n": 67 }
]

Error Handling

The include=attributes query param is required — without it the attributes array is omitted. Verify your API account has store_v2_customers_read_only scope.
Segments with fewer than 3 members produce generic personas. The code skips these. Combine low-count segments into an “Other” bucket or use a broader grouping attribute.