If you've ever wanted to ship a niche paid newsletter but the data sourcing felt like a brick wall, this is the writeup for you. The combo of (1) earnings call transcripts as a structured source, (2) an LLM to summarize, and (3) a transactional email API takes a useful product from "I'd need a data analyst" to "I can prototype it Saturday afternoon".

Concrete shape: a free newsletter that emails subscribers a 200-word summary of every earnings call from a specific universe (Mag 7, or a single sector, or your home-country mid-caps), 1-2 minutes after the transcript drops. Convert to paid via a more thorough Pro tier (full transcript link, themes flagged, sector comparisons).

This is a real recipe people are running. Below is what they wire together.

The stack (4 pieces)

  1. EarningsCalls.dev — for the transcripts (Pro tier, $24.99/month, 5,000 requests/month is way more than you'll burn).
  2. Claude / GPT-4.1 — for the summary. ~$0.003 per call summary at current prices.
  3. Resend / Postmark — for transactional emails. Free tier covers your first 1,000+ subscribers.
  4. Beehiiv / Substack / Ghost — your front door + payment processor. Free tier on Beehiiv, no payment needed until you have ~2,500 free subs.

No infrastructure. No database. No queue. One scheduled function.

The minimum-viable code

import requests, openai
from datetime import datetime, timedelta

API_KEY = "ec_..."   # your earningscalls.dev key
BASE = "https://earningscalls.dev/api/v1"
H = {"X-API-Key": API_KEY}

UNIVERSE = ["NVDA","MSFT","AAPL","GOOGL","META","AMZN","TSLA"]

def find_new_calls(since):
    out = []
    for t in UNIVERSE:
        r = requests.get(f"{BASE}/companies/ticker/{t}/latest", headers=H).json()
        call = r.get("data", {})
        if call.get("event_date_time","") > since:
            out.append(call)
    return out

def transcript(call_id):
    return requests.get(f"{BASE}/transcripts/{call_id}?format=full",
                        headers=H).json()["data"]["full_transcript_text"]

def summarize(text, company):
    return openai.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{"role":"user","content":
            f"Summarise this earnings call for {company} in 200 words. "
            f"Hit: revenue, guidance, three key takeaways. Plain prose, no bullets.\n\n{text[:30000]}"
        }]
    ).choices.message.content

def send(subject, body):
    requests.post("https://api.resend.com/emails",
        headers={"Authorization": f"Bearer {os.environ['RESEND']}"},
        json={"from": "[email protected]",
              "to": [s for s in your_subscribers()],
              "subject": subject,
              "html": markdown_to_html(body)})

# Run this every 15 minutes
since = (datetime.utcnow() - timedelta(minutes=15)).isoformat()
for call in find_new_calls(since):
    txt = transcript(call["id"])
    summary = summarize(txt, call["company_name"])
    send(f"{call['company_name']} just reported — {call['transcript_title']}",
         summary)

That's ~50 lines. Add error handling, a subscriber DB, an unsubscribe link, and HTML formatting and you're at 300.

Niches that work

The market for "yet another earnings newsletter" is saturated. Niches that aren't:

The narrower the niche, the higher the conversion to paid.

What it costs to run

Item Monthly
EarningsCalls.dev Pro $24.99
OpenAI / Anthropic (300 summaries × $0.003) ~$1
Resend (1,000 sends) $0
Beehiiv (free tier under 2,500 subs) $0
Total ~$26

Push to $30–40k MRR is plausible if the niche is right. We've seen indie devs hit $4k MRR in 3 months with a tight focus on one sector.

Where the API earns its keep

Get a key →