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

Your winning email copy is locked inside HubSpot engagement records. You extract emails from Closed Won deals, distill a Brand Voice from the highest-converting messaging, then generate new variations that carry the same tone and persuasion.

Architecture

Code

import os, requests
from openai import OpenAI

HS = os.environ["HUBSPOT_ACCESS_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
HB = "https://api.hubapi.com/crm/v3"
MB = "https://app.mavera.io/api/v1"

# 1. Closed Won deals
deals = requests.post(f"{HB}/objects/deals/search",
    headers={"Authorization": f"Bearer {HS}"},
    json={
        "filterGroups": [{"filters": [{"propertyName": "dealstage", "operator": "EQ", "value": "closedwon"}]}],
        "properties": ["dealname", "amount", "closedate"],
        "sorts": [{"propertyName": "closedate", "direction": "DESCENDING"}],
        "limit": 15,
    },
).json().get("results", [])

# 2. Collect winning email copy
winning_emails = []
for deal in deals:
    assocs = requests.get(f"{HB}/objects/deals/{deal['id']}/associations/emails",
        headers={"Authorization": f"Bearer {HS}"}).json().get("results", [])
    for a in assocs[:5]:
        email = requests.get(f"{HB}/objects/emails/{a['id']}",
            headers={"Authorization": f"Bearer {HS}"},
            params={"properties": "hs_email_subject,hs_email_text,hs_email_direction"},
        ).json().get("properties", {})
        if email.get("hs_email_subject") and email.get("hs_email_direction") == "EMAIL":
            winning_emails.append(f"Subject: {email['hs_email_subject']}\n{email.get('hs_email_text','')[:800]}")

# 3. Create Brand Voice
samples = "\n\n---\n\n".join(winning_emails[:10])
bv = requests.post(f"{MB}/brand-voices",
    headers={"Authorization": f"Bearer {MV}", "Content-Type": "application/json"},
    json={"name": "HubSpot Won Email Voice", "samples": [samples]},
).json()
print(f"Brand Voice: {bv['id']}")

# 4. Generate variations
gen = requests.post(f"{MB}/generations",
    headers={"Authorization": f"Bearer {MV}", "Content-Type": "application/json"},
    json={
        "brand_voice_id": bv["id"],
        "prompt": "Write 3 sales email variants for a mid-market SaaS prospect. Subject line + 150-word body each. Match the winning tone.",
        "count": 3,
    },
).json()
for i, g in enumerate(gen.get("results", [gen]), 1):
    print(f"\nVariant {i}:\n{g.get('content', g.get('text',''))[:300]}")

Example Output

Brand Voice: bv_won_email_9f3a

Variant 1: Subject: Quick question about your Q3 pipeline
Hey [Name], I noticed [Company] is scaling — congrats. We helped [Similar Co]
cut pipeline review time by 40%. Worth a 15-min call?

Variant 2: Subject: [Company] + [Product] — a thought
Your growth caught my eye. We work with companies at your stage to solve
[specific pain]. I put together a quick brief — want it?

Error Handling

Not all deals have associated emails. Confirm your team logs emails to deals in HubSpot Settings.
Under ~200 words total produces a generic voice. Aim for 5–10 emails, 100+ words each.

HubSpot Integration

Brand Voice API